From 2968bf8241d2969c4d51f1651fc3f8c7688b2fca Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 15 Dec 2021 12:17:19 +0000 Subject: merge branch perms_ng into dev --- Zotlabs/Access/PermissionLimits.php | 2 +- Zotlabs/Access/PermissionRoles.php | 79 ++- Zotlabs/Access/Permissions.php | 37 +- Zotlabs/Daemon/Notifier.php | 12 + Zotlabs/Lib/AccessList.php | 239 +++++---- Zotlabs/Lib/Activity.php | 30 +- Zotlabs/Lib/Connect.php | 5 +- Zotlabs/Lib/Enotify.php | 2 +- Zotlabs/Lib/Group.php | 405 --------------- Zotlabs/Lib/Libzot.php | 43 +- Zotlabs/Lib/Permcat.php | 130 ++++- Zotlabs/Lib/ThreadItem.php | 31 +- Zotlabs/Module/Acl.php | 8 +- Zotlabs/Module/Admin/Site.php | 4 +- Zotlabs/Module/Apschema.php | 5 +- Zotlabs/Module/Channel.php | 4 + Zotlabs/Module/Connections.php | 126 +++-- Zotlabs/Module/Connedit.php | 798 +++++++++++------------------ Zotlabs/Module/Contactedit.php | 668 ++++++++++++++++++++++++ Zotlabs/Module/Contactgroup.php | 26 +- Zotlabs/Module/Defperms.php | 21 +- Zotlabs/Module/Follow.php | 4 +- Zotlabs/Module/Group.php | 67 ++- Zotlabs/Module/Item.php | 36 +- Zotlabs/Module/Network.php | 7 +- Zotlabs/Module/New_channel.php | 4 +- Zotlabs/Module/Permcats.php | 148 ++++-- Zotlabs/Module/Profiles.php | 71 ++- Zotlabs/Module/Regate.php | 2 +- Zotlabs/Module/Settings/Channel.php | 714 +++++++------------------- Zotlabs/Module/Settings/Privacy.php | 127 +++++ Zotlabs/Module/Uexport.php | 4 + Zotlabs/Update/_1249.php | 31 ++ Zotlabs/Widget/Collections.php | 6 +- Zotlabs/Widget/Messages.php | 2 +- Zotlabs/Widget/Permcats.php | 79 +++ Zotlabs/Widget/Profile.php | 10 +- Zotlabs/Widget/Settings_menu.php | 5 + app/group.apd | 4 +- boot.php | 8 +- include/attach.php | 6 +- include/channel.php | 49 +- include/connections.php | 3 +- include/conversation.php | 28 +- include/group.php | 2 +- include/items.php | 202 ++++++-- include/nav.php | 6 +- include/permissions.php | 40 +- include/selectors.php | 14 +- include/text.php | 64 ++- tests/unit/Access/PermissionLimitsTest.php | 7 +- tests/unit/Access/PermissionRolesTest.php | 26 +- tests/unit/Access/PermissionsTest.php | 14 +- view/css/mod_connections.css | 18 +- view/css/widgets.css | 5 +- view/js/main.js | 15 +- view/js/mod_connections.js | 2 +- view/pdl/mod_chat.pdl | 2 +- view/pdl/mod_connections.pdl | 3 - view/pdl/mod_connedit.pdl | 2 - view/pdl/mod_import_items.pdl | 3 + view/pdl/mod_permcats.pdl | 7 + view/pdl/mod_profperm.pdl | 2 +- view/pdl/mod_viewconnections.pdl | 2 +- view/theme/redbasic/css/style.css | 19 +- view/theme/redbasic/schema/Focus-Boxy.css | 22 +- view/tpl/abook_edit.tpl | 164 +++--- view/tpl/admin_site.tpl | 2 +- view/tpl/connection_template.tpl | 21 +- view/tpl/connections.tpl | 24 +- view/tpl/connstatus.tpl | 2 +- view/tpl/contact_edit.tpl | 133 +++++ view/tpl/contact_edit_header.tpl | 9 + view/tpl/contact_edit_modal.tpl | 152 ++++++ view/tpl/contact_edit_tools.tpl | 14 + view/tpl/conv_frame.tpl | 1 + view/tpl/conv_item.tpl | 4 +- view/tpl/conv_list.tpl | 2 +- view/tpl/conversation.tpl | 6 +- view/tpl/field_acheckbox.tpl | 41 +- view/tpl/field_checkbox.tpl | 2 +- view/tpl/group_edit.tpl | 2 + view/tpl/group_selection.tpl | 12 +- view/tpl/group_side.tpl | 4 +- view/tpl/micropro_card.tpl | 2 +- view/tpl/new_channel.tpl | 12 +- view/tpl/notes.tpl | 2 +- view/tpl/permcats.tpl | 68 +-- view/tpl/privacy_groups.tpl | 2 + view/tpl/profile_edit.tpl | 12 +- view/tpl/profile_vcard.tpl | 16 +- view/tpl/search_item.tpl | 2 +- view/tpl/settings.tpl | 63 +-- view/tpl/settings_privacy.tpl | 56 ++ 94 files changed, 3138 insertions(+), 2259 deletions(-) delete mode 100644 Zotlabs/Lib/Group.php create mode 100644 Zotlabs/Module/Contactedit.php create mode 100644 Zotlabs/Module/Settings/Privacy.php create mode 100644 Zotlabs/Update/_1249.php create mode 100644 Zotlabs/Widget/Permcats.php create mode 100644 view/pdl/mod_import_items.pdl create mode 100644 view/pdl/mod_permcats.pdl create mode 100644 view/tpl/contact_edit.tpl create mode 100644 view/tpl/contact_edit_header.tpl create mode 100644 view/tpl/contact_edit_modal.tpl create mode 100644 view/tpl/contact_edit_tools.tpl create mode 100644 view/tpl/settings_privacy.tpl diff --git a/Zotlabs/Access/PermissionLimits.php b/Zotlabs/Access/PermissionLimits.php index fb5fe6133..7a574ba6a 100644 --- a/Zotlabs/Access/PermissionLimits.php +++ b/Zotlabs/Access/PermissionLimits.php @@ -89,4 +89,4 @@ class PermissionLimits { return false; } -} \ No newline at end of file +} diff --git a/Zotlabs/Access/PermissionRoles.php b/Zotlabs/Access/PermissionRoles.php index 998b6d8d2..2078b52a8 100644 --- a/Zotlabs/Access/PermissionRoles.php +++ b/Zotlabs/Access/PermissionRoles.php @@ -17,7 +17,7 @@ class PermissionRoles { * @return number */ static public function version() { - return 2; + return 3; } static function role_perms($role) { @@ -27,6 +27,54 @@ class PermissionRoles { $ret['role'] = $role; switch($role) { + + case 'public': + $ret['default_collection'] = false; + $ret['perms_connect'] = [ + 'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki', + 'send_stream', 'post_comments', 'post_mail', 'post_wall', 'chat', 'post_like', 'republish' + ]; + $ret['limits'] = PermissionLimits::Std_Limits(); + $ret['limits']['post_comments'] = PERMS_AUTHED; + $ret['limits']['post_mail'] = PERMS_AUTHED; + $ret['limits']['post_like'] = PERMS_AUTHED; + $ret['limits']['chat'] = PERMS_AUTHED; + break; + + // Hubzilla default role + case 'personal': + $ret['default_collection'] = true; + $ret['perms_connect'] = [ + 'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki', + 'send_stream', 'post_comments', 'post_mail', 'chat', 'post_like' + ]; + $ret['limits'] = PermissionLimits::Std_Limits(); + $ret['limits']['view_contacts'] = PERMS_SPECIFIC; + break; + + case 'group': + $ret['default_collection'] = false; + $ret['perms_connect'] = [ + 'view_stream', 'view_profile', 'view_contacts', 'view_storage', + 'view_pages', 'view_wiki', 'post_wall', 'post_comments', + 'post_mail', 'post_like', 'chat' + ]; + $ret['limits'] = PermissionLimits::Std_Limits(); + $ret['channel_type'] = 'group'; + break; + + // Provide some defaults for the custom role so that we do not start + // with no permissions at all if we create a new channel with this role + case 'custom': + $ret['default_collection'] = true; + $ret['perms_connect'] = [ + 'view_stream', 'view_profile', 'view_contacts', 'view_storage', 'view_pages', 'view_wiki', + 'send_stream', 'post_comments', 'post_mail', 'chat', 'post_like' + ]; + $ret['limits'] = PermissionLimits::Std_Limits(); + break; + +/* case 'social': $ret['perms_auto'] = false; $ret['default_collection'] = false; @@ -193,13 +241,14 @@ class PermissionRoles { $ret['channel_type'] = 'group'; break; +*/ - case 'custom': default: break; } $x = get_config('system','role_perms'); + // let system settings over-ride any or all if($x && is_array($x) && array_key_exists($role,$x)) $ret = array_merge($ret,$x[$role]); @@ -284,6 +333,7 @@ class PermissionRoles { */ static public function roles() { $roles = [ + t('Social Networking') => [ 'social_federation' => t('Social - Federation'), 'social' => t('Social - Mostly Public'), @@ -317,4 +367,29 @@ class PermissionRoles { return $roles; } + /** + * @brief Array with translated role names and grouping. + * + * Return an associative array with role names that can be used + * to create select groups like in \e field_select_grouped.tpl. + * + * @return array + */ + static public function channel_roles() { + $channel_roles = [ + //'public' => [t('Public'), t('A very permissive role suited for participation in the fediverse')], + //'personal' => [t('Personal'), t('The $Projectname default role suited for a personal channel')], + //'forum' => [t('Community forum'), t('This role configures your channel to act as an community forum')], + //'custom' => [t('Custom'), t('This role comes with the presets of the personal role but allows you to configure it to your needs')] + 'public' => t('Public'), + 'personal' => t('Personal'), + 'group' => t('Community forum'), + 'custom' => t('Custom') + ]; + + call_hooks('list_channel_roles', $channel_roles); + + return $channel_roles; + } + } diff --git a/Zotlabs/Access/Permissions.php b/Zotlabs/Access/Permissions.php index 45dd30d69..09f4c9678 100644 --- a/Zotlabs/Access/Permissions.php +++ b/Zotlabs/Access/Permissions.php @@ -41,7 +41,7 @@ class Permissions { * @return number */ static public function version() { - return 2; + return 3; } /** @@ -67,9 +67,9 @@ class Permissions { 'post_comments' => t('Can comment on or like my posts'), 'post_mail' => t('Can send me direct messages'), 'post_like' => t('Can like/dislike profiles and profile things'), - 'tag_deliver' => t('Can forward direct messages to all my channel connections (forum)'), 'chat' => t('Can chat with me'), - 'republish' => t('Can source my public posts in derived channels'), + 'republish' => t('Can source/mirror my public posts in derived channels'), + //'tag_deliver' => t('Can forward to my contacts via direct messages (forum)'), 'delegate' => t('Can administer my channel') ]; @@ -217,25 +217,23 @@ class Permissions { $my_perms = []; $permcat = null; - $automatic = 0; + $automatic = get_pconfig($channel_id, 'system', 'autoperms'); // If a default permcat exists, use that - $pc = ((feature_enabled($channel_id, 'permcats')) ? get_pconfig($channel_id, 'system', 'default_permcat') : 'default'); - if (!in_array($pc, ['', 'default'])) { - $pcp = new Zlib\Permcat($channel_id); - $permcat = $pcp->fetch($pc); - if ($permcat && $permcat['perms']) { - foreach ($permcat['perms'] as $p) { - $my_perms[$p['name']] = $p['value']; - } + $pc = get_pconfig($channel_id, 'system', 'default_permcat', 'default'); + $pcp = new Zlib\Permcat($channel_id); + $permcat = $pcp->fetch($pc); + if ($permcat && $permcat['perms']) { + foreach ($permcat['perms'] as $p) { + $my_perms[$p['name']] = $p['value']; } } // look up the permission role to see if it specified auto-connect // and if there was no permcat or a default permcat, set the perms // from the role - +/* $role = get_pconfig($channel_id, 'system', 'permissions_role'); if ($role) { $xx = PermissionRoles::role_perms($role); @@ -247,11 +245,12 @@ class Permissions { $my_perms = Permissions::FilledPerms($default_perms); } } +*/ // If we reached this point without having any permission information, // it is likely a custom permissions role. First see if there are any // automatic permissions. - +/* if (!$my_perms) { $m = Permissions::FilledAutoperms($channel_id); if ($m) { @@ -259,11 +258,12 @@ class Permissions { $my_perms = $m; } } - +*/ // If we reached this point with no permissions, the channel is using // custom perms but they are not automatic. They will be stored in abconfig with // the channel's channel_hash (the 'self' connection). +/* if (!$my_perms) { $r = q("select channel_hash from channel where channel_id = %d", intval($channel_id) @@ -280,10 +280,10 @@ class Permissions { } } } - - return (['perms' => $my_perms, 'automatic' => $automatic]); +*/ + return (['perms' => $my_perms, 'automatic' => $automatic, 'role' => $pc]); } - +/* static public function serialise($p) { $n = []; if ($p) { @@ -295,4 +295,5 @@ class Permissions { } return implode(',', $n); } +*/ } diff --git a/Zotlabs/Daemon/Notifier.php b/Zotlabs/Daemon/Notifier.php index 4ca109495..23bddae8f 100644 --- a/Zotlabs/Daemon/Notifier.php +++ b/Zotlabs/Daemon/Notifier.php @@ -630,6 +630,18 @@ class Notifier { // default: zot protocol + // Prevent zot6 delivery of group comment boosts, which are not required for conversational platforms. + // ActivityPub conversational platforms may wish to filter these if they don't want or require them. + // We will assume here that if $target_item exists and has a verb that it is an actual item structure + // so we won't need to check the existence of the other item fields prior to evaluation. + + // This shouldn't produce false positives on comment boosts that were generated on other platforms + // because we won't be delivering them. + + if (isset($target_item) && isset($target_item['verb']) && $target_item['verb'] === 'Announce' && $target_item['author_xchan'] === $target_item['owner_xchan'] && ! intval($target_item['item_thread_top'])) { + continue; + } + $hash = new_uuid(); $env = (($hub_env && $hub_env[$hub['hubloc_site_id']]) ? $hub_env[$hub['hubloc_site_id']] : ''); diff --git a/Zotlabs/Lib/AccessList.php b/Zotlabs/Lib/AccessList.php index 3c008f8c7..51c100afb 100644 --- a/Zotlabs/Lib/AccessList.php +++ b/Zotlabs/Lib/AccessList.php @@ -1,38 +1,37 @@ -may apply to this list and any future members. If this is not what you intended, please create another list with a different name.') . EOL); + notice(t('A deleted list with this name was revived. Existing item permissions may apply to this list and any future members. If this is not what you intended, please create another list with a different name.') . EOL); } - return true; + $hash = self::by_id($uid, $r); + return $hash; } $hash = new_uuid(); - $r = q("INSERT INTO pgrp ( hash, uid, visible, gname ) + $r = q("INSERT INTO pgrp ( hash, uid, visible, gname ) VALUES( '%s', %d, %d, '%s' ) ", dbesc($hash), intval($uid), @@ -42,12 +41,12 @@ class AccessList { $ret = $r; } - Libsync::build_sync_packet($uid,null,true); - return $ret; - } + Libsync::build_sync_packet($uid, null, true); + return (($ret) ? $hash : $ret); + } - static function remove($uid,$name) { + static function remove($uid, $name) { $ret = false; if ($uid && $name) { $r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1", @@ -55,36 +54,36 @@ class AccessList { dbesc($name) ); if ($r) { - $group_id = $r[0]['id']; + $group_id = $r[0]['id']; $group_hash = $r[0]['hash']; } else { return false; } - + // remove group from default posting lists $r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1", - intval($uid) + intval($uid) ); if ($r) { $user_info = array_shift($r); - $change = false; + $change = false; if ($user_info['channel_default_group'] == $group_hash) { $user_info['channel_default_group'] = ''; - $change = true; + $change = true; } if (strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) { $user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']); - $change = true; + $change = true; } if (strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) { $user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']); - $change = true; + $change = true; } if ($change) { - q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s' + q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s' WHERE channel_id = %d", intval($user_info['channel_default_group']), dbesc($user_info['channel_allow_gid']), @@ -110,16 +109,16 @@ class AccessList { } - Libsync::build_sync_packet($uid,null,true); + Libsync::build_sync_packet($uid, null, true); return $ret; } // returns the integer id of an access group owned by $uid and named $name // or false. - - static function byname($uid,$name) { - if (! ($uid && $name)) { + + static function by_name($uid, $name) { + if (!($uid && $name)) { return false; } $r = q("SELECT id FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1", @@ -132,11 +131,11 @@ class AccessList { return false; } - static function by_id($uid,$id) { - if (! ($uid && $id)) { + static function by_id($uid, $id) { + if (!($uid && $id)) { return false; } - + $r = q("SELECT * FROM pgrp WHERE uid = %d AND id = %d and deleted = 0", intval($uid), intval($id) @@ -147,10 +146,8 @@ class AccessList { return false; } - - - static function rec_byhash($uid,$hash) { - if (! ( $uid && $hash)) { + static function by_hash($uid, $hash) { + if (!($uid && $hash)) { return false; } $r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1", @@ -163,46 +160,43 @@ class AccessList { return false; } + static function member_remove($uid, $name, $member) { + $gid = self::by_name($uid, $name); - static function member_remove($uid,$name,$member) { - $gid = self::byname($uid,$name); - if (! $gid) { - return false; - } - if (! ($uid && $gid && $member)) { + if (!($uid && $gid && $member)) { return false; } + $r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ", intval($uid), intval($gid), dbesc($member) ); - Libsync::build_sync_packet($uid,null,true); + Libsync::build_sync_packet($uid, null, true); return $r; } - - static function member_add($uid,$name,$member,$gid = 0) { - if (! $gid) { - $gid = self::byname($uid,$name); + static function member_add($uid, $name, $member, $gid = 0) { + if (!$gid) { + $gid = self::by_name($uid, $name); } - if (! ($gid && $uid && $member)) { + if (!($gid && $uid && $member)) { return false; } - $r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1", + $r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1", intval($uid), intval($gid), dbesc($member) ); if ($r) { - return true; // You might question this, but - // we indicate success because the group member was in fact created - // -- It was just created at another time + return true; // You might question this, but + // we indicate success because the group member was in fact created + // -- It was just created at another time } - else { + else { $r = q("INSERT INTO pgrp_member (uid, gid, xchan) VALUES( %d, %d, '%s' ) ", intval($uid), @@ -210,15 +204,14 @@ class AccessList { dbesc($member) ); } - Libsync::build_sync_packet($uid,null,true); + Libsync::build_sync_packet($uid, null, true); return $r; } - static function members($uid, $gid) { $ret = []; if (intval($gid)) { - $r = q("SELECT * FROM pgrp_member + $r = q("SELECT * FROM pgrp_member LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ", intval($gid), @@ -232,7 +225,7 @@ class AccessList { return $ret; } - static function members_xchan($uid,$gid) { + static function members_xchan($uid, $gid) { $ret = []; if (intval($gid)) { $r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d", @@ -248,99 +241,123 @@ class AccessList { return $ret; } - static function members_profile_xchan($uid,$gid) { + static function profile_members_xchan($uid,$gid) { $ret = []; - if (intval($gid)) { + + if(intval($gid)) { $r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d", intval($gid), intval($uid) ); - if ($r) { - foreach($r as $rv) { - $ret[] = $rv['xchan']; + if($r) { + foreach($r as $rr) { + $ret[] = $rr['xchan']; } } } return $ret; } + static function select($uid, $options) { + $selected = $options['selected'] ?? ''; + $form_id = $options['form_id'] ?? 'accesslist_select'; + $label = $options['label'] ?? t('Select a privacy group'); + $before = $options['before'] ?? []; + $after = $options['after'] ?? []; - - static function select($uid,$group = '') { - $grps = []; + $o = ''; + + $grps[] = [ + 'name' => '', + 'id' => '0', + 'selected' => false + ]; + + if ($before) { + $grps[] = $before; + } $r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", intval($uid) ); - $grps[] = [ 'name' => '', 'hash' => '0', 'selected' => '' ]; - if ($r) { - foreach ($r as $rr) { - $grps[] = [ 'name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '') ]; + + if($r) { + foreach($r as $rr) { + $grps[] = [ + 'name' => $rr['gname'], + 'id' => $rr['hash'], + 'selected' => ($selected == $rr['hash']) + ]; } + } + if ($after) { + $grps[] = $after; } - - return replace_macros(get_markup_template('group_selection.tpl'), [ - '$label' => t('Add new connections to this access list'), - '$groups' => $grps - ]); - } + logger('select: ' . print_r($grps,true), LOGGER_DATA); - static function widget($every="connections",$each="lists",$edit = false, $group_id = 0, $cid = '',$mode = 1) { + $o = replace_macros(get_markup_template('group_selection.tpl'), array( + '$label' => $label, + '$form_id' => $form_id, + '$groups' => $grps + )); + + return $o; + } - $o = ''; + + static function widget($every = "connections", $each = "lists", $edit = false, $group_id = 0, $cid = '', $mode = 1) { $groups = []; - $r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", + $r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", intval($_SESSION['uid']) ); $member_of = []; if ($cid) { - $member_of = self::containing(local_channel(),$cid); - } + $member_of = self::containing(local_channel(), $cid); + } if ($r) { foreach ($r as $rr) { $selected = (($group_id == $rr['id']) ? ' group-selected' : ''); - + if ($edit) { - $groupedit = [ 'href' => "lists/".$rr['id'], 'title' => t('edit') ]; - } + $groupedit = ['href' => "lists/" . $rr['id'], 'title' => t('edit')]; + } else { $groupedit = null; } - + $groups[] = [ - 'id' => $rr['id'], - 'enc_cid' => base64url_encode($cid), - 'cid' => $cid, - 'text' => $rr['gname'], - 'selected' => $selected, - 'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''), - 'edit' => $groupedit, - 'ismember' => in_array($rr['id'],$member_of), + 'id' => $rr['id'], + 'enc_cid' => base64url_encode($cid), + 'cid' => $cid, + 'text' => $rr['gname'], + 'selected' => $selected, + 'href' => (($mode == 0) ? $each . '?f=&gid=' . $rr['id'] : $each . "/" . $rr['id']) . ((x($_GET, 'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET, 'order')) ? '&order=' . $_GET['order'] : ''), + 'edit' => $groupedit, + 'ismember' => in_array($rr['id'], $member_of), ]; } } - + return replace_macros(get_markup_template('group_side.tpl'), [ - '$title' => t('Lists'), - '$edittext' => t('Edit list'), - '$createtext' => t('Create new list'), - '$ungrouped' => (($every === 'contacts') ? t('Channels not in any access list') : ''), - '$groups' => $groups, - '$add' => t('add'), + '$title' => t('Lists'), + '$edittext' => t('Edit list'), + '$createtext' => t('Create new list'), + '$ungrouped' => (($every === 'contacts') ? t('Channels not in any access list') : ''), + '$groups' => $groups, + '$add' => t('add'), ]); } - static function expand($g) { - if (! (is_array($g) && count($g))) { + if (!(is_array($g) && count($g))) { return []; } @@ -350,8 +367,8 @@ class AccessList { // private profile linked virtual groups foreach ($g as $gv) { - if (substr($gv,0,3) === 'vp.') { - $profile_hash = substr($gv,3); + if (substr($gv, 0, 3) === 'vp.') { + $profile_hash = substr($gv, 3); if ($profile_hash) { $r = q("select abook_xchan from abook where abook_profile = '%s'", dbesc($profile_hash) @@ -366,10 +383,10 @@ class AccessList { else { $x[] = $gv; } - } + } if ($x) { - stringify_array_elms($x,true); + stringify_array_elms($x, true); $groups = implode(',', $x); if ($groups) { $r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))"); @@ -383,9 +400,8 @@ class AccessList { return $ret; } - static function member_of($c) { - $r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id + $r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ", dbesc($c) ); @@ -393,7 +409,7 @@ class AccessList { return $r; } - static function containing($uid,$c) { + static function containing($uid, $c) { $r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ", intval($uid), @@ -405,7 +421,8 @@ class AccessList { foreach ($r as $rv) $ret[] = $rv['gid']; } - + return $ret; } -} \ No newline at end of file + +} diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 664886fc2..8e5a4e1a6 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -886,10 +886,6 @@ class Activity { else return []; - if (strpos($i['body'], '[/share]') !== false) { - $i['obj'] = null; - } - if ($i['obj']) { if (!is_array($i['obj'])) { $i['obj'] = json_decode($i['obj'], true); @@ -899,8 +895,10 @@ class Activity { } $obj = self::encode_object($i['obj']); - if ($obj) + + if ($obj) { $ret['object'] = $obj; + } else return []; } @@ -1042,7 +1040,7 @@ class Activity { $tmp = expand_acl($i['allow_cid']); $list = stringify_array($tmp, true); if ($list) { - $details = q("select hubloc_id_url from hubloc where hubloc_hash in (" . $list . ") and hubloc_id_url != ''"); + $details = q("select hubloc_id_url from hubloc where hubloc_hash in (" . $list . ") and hubloc_id_url != '' and hubloc_deleted = 0"); if ($details) { foreach ($details as $d) { $ret[] = $d['hubloc_id_url']; @@ -1089,10 +1087,11 @@ class Activity { $ret['type'] = 'Person'; if ($c) { - $role = get_pconfig($c['channel_id'], 'system', 'permissions_role'); - if (strpos($role, 'forum') !== false) { + if (get_pconfig($c['channel_id'], 'system', 'group_actor')) { $ret['type'] = 'Group'; } + + $ret['manuallyApprovesFollowers'] = ((get_pconfig($c['channel_id'], 'system', 'autoperms')) ? false : true); } if ($c) { @@ -1554,9 +1553,9 @@ class Activity { /* If there is a default group for this channel and permissions are automatic, add this member to it */ if ($channel['channel_default_group'] && $automatic) { - $g = Group::rec_byhash($channel['channel_id'], $channel['channel_default_group']); + $g = AccessList::by_hash($channel['channel_id'], $channel['channel_default_group']); if ($g) - Group::member_add($channel['channel_id'], '', $ret['xchan_hash'], $g['id']); + AccessList::member_add($channel['channel_id'], '', $ret['xchan_hash'], $g['id']); } @@ -2692,6 +2691,17 @@ class Activity { // set the owner to the owner of the parent $item['owner_xchan'] = $p[0]['owner_xchan']; + // quietly reject group comment boosts by group owner + // (usually only sent via ActivityPub so groups will work on microblog platforms) + // This catches those activities if they slipped in via a conversation fetch + + if ($p[0]['parent_mid'] !== $item['parent_mid']) { + if ($item['verb'] === 'Announce' && $item['author_xchan'] === $item['owner_xchan']) { + logger('group boost activity by group owner rejected'); + return; + } + } + // check permissions against the author, not the sender $allowed = perm_is_allowed($channel['channel_id'], $item['author_xchan'], 'post_comments'); if ((!$allowed)/* && $permit_mentions*/) { diff --git a/Zotlabs/Lib/Connect.php b/Zotlabs/Lib/Connect.php index 38fe69995..0b9ff7089 100644 --- a/Zotlabs/Lib/Connect.php +++ b/Zotlabs/Lib/Connect.php @@ -261,7 +261,8 @@ class Connect { 'abook_feed' => intval(($xchan['xchan_network'] === 'rss') ? 1 : 0), 'abook_created' => datetime_convert(), 'abook_updated' => datetime_convert(), - 'abook_instance' => (($singleton) ? z_root() : '') + 'abook_instance' => (($singleton) ? z_root() : ''), + 'abook_role' => get_pconfig($uid, 'system', 'default_permcat', 'default') ] ); } @@ -300,7 +301,7 @@ class Connect { /** If there is a default group for this channel, add this connection to it */ if ($default_group) { - $g = AccessList::rec_byhash($uid,$default_group); + $g = AccessList::by_hash($uid,$default_group); if ($g) { AccessList::member_add($uid,'',$xchan_hash,$g['id']); } diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php index fdc7d4567..2e483cb92 100644 --- a/Zotlabs/Lib/Enotify.php +++ b/Zotlabs/Lib/Enotify.php @@ -902,7 +902,7 @@ class Enotify { static public function format_intros($rr) { return [ - 'notify_link' => z_root() . '/connections/ifpending', + 'notify_link' => z_root() . '/connections#' . $rr['abook_id'], 'name' => $rr['xchan_name'], 'addr' => $rr['xchan_addr'], 'url' => $rr['xchan_url'], diff --git a/Zotlabs/Lib/Group.php b/Zotlabs/Lib/Group.php deleted file mode 100644 index a4ff4fced..000000000 --- a/Zotlabs/Lib/Group.php +++ /dev/null @@ -1,405 +0,0 @@ -may apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL); - } - return true; - } - - do { - $dups = false; - $hash = random_string(32) . str_replace(['<','>'],['.','.'], $name); - - $r = q("SELECT id FROM pgrp WHERE hash = '%s' LIMIT 1", dbesc($hash)); - if($r) - $dups = true; - } while($dups == true); - - - $r = q("INSERT INTO pgrp ( hash, uid, visible, gname ) - VALUES( '%s', %d, %d, '%s' ) ", - dbesc($hash), - intval($uid), - intval($public), - dbesc($name) - ); - $ret = $r; - } - - Libsync::build_sync_packet($uid,null,true); - return $ret; - } - - - static function remove($uid,$name) { - $ret = false; - if(x($uid) && x($name)) { - $r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1", - intval($uid), - dbesc($name) - ); - if($r) { - $group_id = $r[0]['id']; - $group_hash = $r[0]['hash']; - } - - if(! $group_id) - return false; - - // remove group from default posting lists - $r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1", - intval($uid) - ); - if($r) { - $user_info = $r[0]; - $change = false; - - if($user_info['channel_default_group'] == $group_hash) { - $user_info['channel_default_group'] = ''; - $change = true; - } - if(strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) { - $user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']); - $change = true; - } - if(strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) { - $user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']); - $change = true; - } - - if($change) { - q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s' - WHERE channel_id = %d", - intval($user_info['channel_default_group']), - dbesc($user_info['channel_allow_gid']), - dbesc($user_info['channel_deny_gid']), - intval($uid) - ); - } - } - - // remove all members - $r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d ", - intval($uid), - intval($group_id) - ); - - // remove group - $r = q("UPDATE pgrp SET deleted = 1 WHERE uid = %d AND gname = '%s'", - intval($uid), - dbesc($name) - ); - - $ret = $r; - - } - - Libsync::build_sync_packet($uid,null,true); - - return $ret; - } - - - static function byname($uid,$name) { - if((! $uid) || (! strlen($name))) - return false; - $r = q("SELECT * FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1", - intval($uid), - dbesc($name) - ); - if($r) - return $r[0]['id']; - return false; - } - - - static function rec_byhash($uid,$hash) { - if((! $uid) || (! strlen($hash))) - return false; - $r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1", - intval($uid), - dbesc($hash) - ); - if($r) - return $r[0]; - return false; - } - - - static function member_remove($uid,$name,$member) { - $gid = self::byname($uid,$name); - if(! $gid) - return false; - if(! ( $uid && $gid && $member)) - return false; - $r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ", - intval($uid), - intval($gid), - dbesc($member) - ); - - Libsync::build_sync_packet($uid,null,true); - - return $r; - } - - - static function member_add($uid,$name,$member,$gid = 0) { - if(! $gid) - $gid = self::byname($uid,$name); - if((! $gid) || (! $uid) || (! $member)) - return false; - - $r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1", - intval($uid), - intval($gid), - dbesc($member) - ); - if($r) - return true; // You might question this, but - // we indicate success because the group member was in fact created - // -- It was just created at another time - if(! $r) - $r = q("INSERT INTO pgrp_member (uid, gid, xchan) - VALUES( %d, %d, '%s' ) ", - intval($uid), - intval($gid), - dbesc($member) - ); - - Libsync::build_sync_packet($uid,null,true); - - return $r; - } - - - static function members($gid) { - $ret = array(); - if(intval($gid)) { - $r = q("SELECT * FROM pgrp_member - LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan - WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ", - intval($gid), - intval(local_channel()), - intval(local_channel()) - ); - if($r) - $ret = $r; - } - return $ret; - } - - static function members_xchan($gid) { - $ret = []; - if(intval($gid)) { - $r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d", - intval($gid), - intval(local_channel()) - ); - if($r) { - foreach($r as $rr) { - $ret[] = $rr['xchan']; - } - } - } - return $ret; - } - - static function members_profile_xchan($uid,$gid) { - $ret = []; - - if(intval($gid)) { - $r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d", - intval($gid), - intval($uid) - ); - if($r) { - foreach($r as $rr) { - $ret[] = $rr['xchan']; - } - } - } - return $ret; - } - - - - - static function select($uid,$group = '') { - - $grps = []; - $o = ''; - - $r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", - intval($uid) - ); - $grps[] = array('name' => '', 'hash' => '0', 'selected' => ''); - if($r) { - foreach($r as $rr) { - $grps[] = array('name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '')); - } - - } - logger('select: ' . print_r($grps,true), LOGGER_DATA); - - $o = replace_macros(get_markup_template('group_selection.tpl'), array( - '$label' => t('Add new connections to this privacy group'), - '$groups' => $grps - )); - return $o; - } - - - - - static function widget($every="connections",$each="group",$edit = false, $group_id = 0, $cid = '',$mode = 1) { - - $o = ''; - - if(! (local_channel() && feature_enabled(local_channel(),'groups'))) { - return ''; - } - - $groups = array(); - - $r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", - intval($_SESSION['uid']) - ); - $member_of = array(); - if($cid) { - $member_of = self::containing(local_channel(),$cid); - } - - if($r) { - foreach($r as $rr) { - $selected = (($group_id == $rr['id']) ? ' group-selected' : ''); - - if ($edit) { - $groupedit = [ 'href' => "group/".$rr['id'], 'title' => t('edit') ]; - } - else { - $groupedit = null; - } - - $groups[] = [ - 'id' => $rr['id'], - 'enc_cid' => base64url_encode($cid), - 'cid' => $cid, - 'text' => $rr['gname'], - 'selected' => $selected, - 'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''), - 'edit' => $groupedit, - 'ismember' => in_array($rr['id'],$member_of), - ]; - } - } - - - $tpl = get_markup_template("group_side.tpl"); - $o = replace_macros($tpl, array( - '$title' => t('Privacy Groups'), - '$edittext' => t('Edit group'), - '$createtext' => t('Add privacy group'), - '$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''), - '$groups' => $groups, - '$add' => t('add'), - )); - - - return $o; - } - - - static function expand($g) { - if(! (is_array($g) && count($g))) - return array(); - - $ret = []; - $x = []; - - // private profile linked virtual groups - - foreach($g as $gv) { - if(substr($gv,0,3) === 'vp.') { - $profile_hash = substr($gv,3); - if($profile_hash) { - $r = q("select abook_xchan from abook where abook_profile = '%s'", - dbesc($profile_hash) - ); - if($r) { - foreach($r as $rv) { - $ret[] = $rv['abook_xchan']; - } - } - } - } - else { - $x[] = $gv; - } - } - - if($x) { - stringify_array_elms($x,true); - $groups = implode(',', $x); - if($groups) { - $r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))"); - if($r) { - foreach($r as $rr) { - $ret[] = $rr['xchan']; - } - } - } - } - return $ret; - } - - - static function member_of($c) { - $r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ", - dbesc($c) - ); - - return $r; - - } - - static function containing($uid,$c) { - - $r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ", - intval($uid), - dbesc($c) - ); - - $ret = array(); - if($r) { - foreach($r as $rr) - $ret[] = $rr['gid']; - } - - return $ret; - } -} \ No newline at end of file diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 31b8f04de..e2cbc66e6 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -386,9 +386,10 @@ class Libzot { else { $p = Permissions::connect_perms($channel['channel_id']); - $my_perms = $p['perms']; + $my_perms = $p['perms']; $automatic = $p['automatic']; + $role = (($automatic) ? $p['role'] : ''); // new connection @@ -410,7 +411,8 @@ class Libzot { 'abook_created' => datetime_convert(), 'abook_updated' => datetime_convert(), 'abook_dob' => $next_birthday, - 'abook_pending' => intval(($automatic) ? 0 : 1) + 'abook_pending' => intval(($automatic) ? 0 : 1), + 'abook_role' => $role ] ); @@ -435,7 +437,7 @@ class Libzot { 'type' => NOTIFY_INTRO, 'from_xchan' => $x['hash'], 'to_xchan' => $channel['channel_hash'], - 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'] + 'link' => z_root() . '/connections#' . $new_connection[0]['abook_id'] ] ); @@ -453,10 +455,10 @@ class Libzot { $default_group = $channel['channel_default_group']; if ($default_group) { - $g = Group::rec_byhash($channel['channel_id'], $default_group); + $g = AccessList::by_hash($channel['channel_id'], $default_group); if ($g) { - Group::member_add($channel['channel_id'], '', $x['hash'], $g['id']); + AccessList::member_add($channel['channel_id'], '', $x['hash'], $g['id']); } } } @@ -1143,6 +1145,7 @@ class Libzot { if ($env['encoding'] === 'activitystreams') { $AS = new ActivityStreams($data); + if (!$AS->is_valid()) { logger('Activity rejected: ' . print_r($data, true)); return; @@ -1158,8 +1161,6 @@ class Libzot { } - - $deliveries = null; if (array_key_exists('recipients', $env) && count($env['recipients'])) { @@ -1592,6 +1593,7 @@ class Libzot { if ((!$tag_delivery) && (!$local_public)) { $allowed = (perm_is_allowed($channel['channel_id'], $sender, $perm)); + if ((!$allowed) && $perm === 'post_comments') { $parent = q("select * from item where mid = '%s' and uid = %d limit 1", dbesc($arr['parent_mid']), @@ -2785,28 +2787,6 @@ class Libzot { if ($deleted || $censored || $sys_channel) $searchable = false; - $public_forum = false; - - $role = get_pconfig($e['channel_id'], 'system', 'permissions_role'); - if ($role === 'forum' || $role === 'repository') { - $public_forum = true; - } - else { - // check if it has characteristics of a public forum based on custom permissions. - $m = Permissions::FilledAutoperms($e['channel_id']); - if ($m) { - foreach ($m as $k => $v) { - if ($k == 'tag_deliver' && intval($v) == 1) - $ch++; - if ($k == 'send_stream' && intval($v) == 0) - $ch++; - } - if ($ch == 2) - $public_forum = true; - } - } - - // This is for birthdays and keywords, but must check access permissions $p = q("select * from profile where uid = %d and is_default = 1", intval($e['channel_id']) @@ -2875,6 +2855,7 @@ class Libzot { ]; $ret['channel_role'] = get_pconfig($e['channel_id'], 'system', 'permissions_role', 'custom'); + $ret['channel_type'] = ((get_pconfig($e['channel_id'], 'system', 'group_actor')) ? 'group' : 'normal'); $hookinfo = [ 'channel_id' => $id, @@ -2890,8 +2871,10 @@ class Libzot { $ret['protocols'] = $hookinfo['protocols']; $ret['searchable'] = $searchable; $ret['adult_content'] = $adult_channel; - $ret['public_forum'] = $public_forum; + // now all forums (public, restricted, and private) set the public_forum flag. So it really means "is a group" + // and has nothing to do with accessibility. + $ret['public_forum'] = get_pconfig($e['channel_id'], 'system', 'group_actor'); $ret['comments'] = map_scope(PermissionLimits::Get($e['channel_id'], 'post_comments')); $ret['mail'] = map_scope(PermissionLimits::Get($e['channel_id'], 'post_mail')); diff --git a/Zotlabs/Lib/Permcat.php b/Zotlabs/Lib/Permcat.php index ca4aed9ed..bda35a9cb 100644 --- a/Zotlabs/Lib/Permcat.php +++ b/Zotlabs/Lib/Permcat.php @@ -4,6 +4,8 @@ namespace Zotlabs\Lib; use Zotlabs\Access\PermissionRoles; use Zotlabs\Access\Permissions; +use Zotlabs\Lib\Libsync; +use Zotlabs\Daemon\Master; /** * @brief Permission Categories. Permission rules for various classes of connections. @@ -79,8 +81,9 @@ class Permcat { $this->permcats[] = [ 'name' => 'default', - 'localname' => t('default','permcat'), + 'localname' => t('Default','permcat'), 'perms' => Permissions::Operms($perms), + 'raw_perms' => $perms, 'system' => 1 ]; @@ -92,6 +95,7 @@ class Permcat { 'name' => $p[$x][0], 'localname' => $p[$x][1], 'perms' => Permissions::Operms(Permissions::FilledPerms($p[$x][2])), + 'raw_perms' => Permissions::FilledPerms($p[$x][2]), 'system' => intval($p[$x][3]) ]; } @@ -128,27 +132,24 @@ class Permcat { } public function load_permcats($uid) { - +/* $permcats = [ - [ 'follower', t('follower','permcat'), - [ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki', - 'post_like' ], 1 + [ 'contributor', t('Contributor','permcat'), + [ 'view_stream','view_profile','view_contacts','view_storage','view_pages', + 'write_storage','post_wall','write_pages','write_wiki','post_comments', 'post_mail', 'post_like', + 'chat' ], 1 ], - [ 'contributor', t('contributor','permcat'), + [ 'muted', t('Muted','permcat'), [ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki', - 'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1 + 'post_comments','write_wiki','post_like' ], 1 ], - [ 'publisher', t('publisher','permcat'), - [ 'view_stream','view_profile','view_contacts','view_storage','view_pages', - 'write_storage','post_wall','write_pages','write_wiki','post_comments','post_like','tag_deliver', - 'chat', 'republish' ], 1 - ] ]; - +*/ if($uid) { $x = q("select * from pconfig where uid = %d and cat = 'permcat'", intval($uid) ); + if($x) { foreach($x as $xv) { $value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']); @@ -183,4 +184,105 @@ class Permcat { PConfig::Delete($channel_id, 'permcat', $name); } -} \ No newline at end of file + /** + * @brief assign a contact role to contacts + * + * @param int $channel_id + * @param string $role the name of the role + * @param array $contacts an array of contact hashes + */ + public static function assign($channel, $role, $contacts) { + + if(!isset($channel['channel_id'])) { + return; + } + + if(!is_array($contacts) || empty($contacts)) { + return; + } + + if(!$role) { + // lookup the default + $role = get_pconfig($channel_id, 'system', 'default_permcat', 'default'); + } + + + // Doublecheck that we do not assign a role to ourself. + // It does not make a difference but could be confusing. + if (in_array($channel['channel_hash'], $contacts)) { + $contacts = array_diff($contacts, [$channel['channel_hash']]); + } + + $all_perms = Permissions::Perms(); + $permcats = new Permcat($channel['channel_id']); + $role_perms = $permcats->fetch($role); + + if (isset($role_perms['error'])) { + return false; + } + + $perms = $role_perms['raw_perms']; + + $values_sql = ''; + stringify_array_elms($contacts, true); + + if ($all_perms && $perms) { + + foreach ($contacts as $contact) { + foreach ($all_perms as $perm => $desc) { + if (array_key_exists($perm, $perms)) { + $values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', " . intval($perms[$perm]) . "),"; + } + else { + $values_sql .= " (" . intval($channel['channel_id']) . ", " . protect_sprintf($contact) . ", 'my_perms', '" . dbesc($perm) . "', 0), "; + } + } + } + } + + $values_sql = rtrim($values_sql, ','); + + dbq("DELETE FROM abconfig WHERE chan = " . intval($channel['channel_id']) . " AND cat = 'my_perms' AND xchan IN (" . protect_sprintf(implode(',', $contacts)) . ")"); + + dbq("INSERT INTO abconfig ( chan, xchan, cat, k, v ) VALUES $values_sql"); + + q("UPDATE abook SET abook_role = '%s' + WHERE abook_xchan IN (" . protect_sprintf(implode(',', $contacts)) . ") AND abook_channel = %d", + dbesc($role), + intval($channel['channel_id']) + ); + + $r = q("SELECT abook.*, xchan.* FROM abook LEFT JOIN xchan ON abook.abook_xchan = xchan.xchan_hash WHERE abook.abook_xchan IN (" . protect_sprintf(implode(',', $contacts)) . ") AND abook.abook_channel = %d AND abook_self = 0", + intval($channel['channel_id']) + ); + + foreach ($r as $rr) { + + if (intval($rr['abook_self'])) { + continue; + } + + Master::Summon([ + 'Notifier', + 'permission_update', + $rr['abook_id'] + ]); + + $clone = $rr; + + unset($clone['abook_id']); + unset($clone['abook_account']); + unset($clone['abook_channel']); + + $abconfig = load_abconfig($channel['channel_id'], $clone['abook_xchan']); + if ($abconfig) + $clone['abconfig'] = $abconfig; + + Libsync::build_sync_packet(0 /* use the current local_channel */, ['abook' => [$clone]]); + + } + + return true; + } + +} diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index cd54fea17..e7cb2d5de 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -3,6 +3,7 @@ namespace Zotlabs\Lib; use Zotlabs\Lib\Apps; +use Zotlabs\Access\AccessList; require_once('include/text.php'); @@ -58,6 +59,9 @@ class ThreadItem { $child = new ThreadItem($item); $this->add_child($child); } + + // performance: we have already added the children + unset($this->data['children']); } // allow a site to configure the order and content of the reaction emoji list @@ -98,11 +102,20 @@ class ThreadItem { $conv = $this->get_conversation(); $observer = $conv->get_observer(); - $lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) - || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) - ? t('Private Message') + $acl = new AccessList(false); + $acl->set($item); + + $lock = ((intval($item['item_private']) || ($item['uid'] == local_channel() && $acl->is_private())) + ? t('Restricted message') : false); - $locktype = $item['item_private']; + + // 1 = restricted message, 2 = direct message + $locktype = intval($item['item_private']); + // 0 = limited based on public policy + if ($item['uid'] == local_channel() && intval($item['item_private']) && !$acl->is_private() && strlen($item['public_policy'])) { + $lock = t('Public Policy'); + $locktype = 0; + } $shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && ($item['item_private'] != 1)) ? true : false); @@ -110,6 +123,16 @@ class ThreadItem { if($item['author']['xchan_network'] === 'rss') $shareable = true; + // @fixme + // Have recently added code to properly handle polls in group reshares by redirecting all of the poll responses to the group. + // Sharing a poll using a regular embedded share is harder because the poll will need to fork. This is due to comment permissions. + // The original poll author may not accept responses from strangers. Forking the poll will receive responses from the sharer's + // followers, but there's no elegant way to merge these two sets of results together. For now, we'll disable sharing polls. + + if ($item['obj_type'] === 'Question') { + $shareable = false; + } + $privacy_warning = false; if(intval($item['item_private']) && ($item['owner']['xchan_network'] === 'activitypub')) { $recips = get_iconfig($item['parent'], 'activitypub', 'recips'); diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index aeb02eeaa..5b37f2707 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -3,9 +3,9 @@ namespace Zotlabs\Module; use Zotlabs\Lib\Libzotdir; +use Zotlabs\Lib\AccessList; require_once 'include/acl_selectors.php'; -require_once 'include/group.php'; /** * @brief ACL selector json backend. @@ -123,7 +123,7 @@ class Acl extends \Zotlabs\Web\Controller { "name" => t('Profile','acl') . ' ' . $rv['profile_name'], "id" => 'vp' . $rv['id'], "xid" => 'vp.' . $rv['profile_guid'], - "uids" => group_get_profile_members_xchan(local_channel(), $rv['id']), + "uids" => AccessList::profile_members_xchan(local_channel(), $rv['id']), "link" => '' ); } @@ -146,14 +146,14 @@ class Acl extends \Zotlabs\Web\Controller { if($r) { foreach($r as $g){ - // logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id'])); + // logger('acl: group: ' . $g['gname'] . ' members: ' . AccessList::members_xchan(local_channel(), $g['id'])); $groups[] = array( "type" => "g", "photo" => "images/twopeople.png", "name" => $g['gname'], "id" => $g['id'], "xid" => $g['hash'], - "uids" => group_get_members_xchan($g['id']), + "uids" => AccessList::members_xchan(local_channel(), $g['id']), "link" => '' ); } diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php index 76e117a84..00095187d 100644 --- a/Zotlabs/Module/Admin/Site.php +++ b/Zotlabs/Module/Admin/Site.php @@ -339,8 +339,8 @@ class Site { // now invert the logic for the setting. $discover_tab = (1 - $discover_tab); - $perm_roles = \Zotlabs\Access\PermissionRoles::roles(); - $default_role = get_config('system','default_permissions_role','social'); + $perm_roles = \Zotlabs\Access\PermissionRoles::channel_roles(); + $default_role = get_config('system','default_permissions_role','personal'); $role = array('permissions_role' , t('Default permission role for new accounts'), $default_role, t('This role will be used for the first channel created after registration.'),$perm_roles); diff --git a/Zotlabs/Module/Apschema.php b/Zotlabs/Module/Apschema.php index eab82eb29..e8d45c522 100644 --- a/Zotlabs/Module/Apschema.php +++ b/Zotlabs/Module/Apschema.php @@ -14,7 +14,7 @@ class Apschema extends \Zotlabs\Web\Controller { 'zot' => z_root() . '/apschema#', 'id' => '@id', 'type' => '@type', - 'commentPolicy' => 'as:commentPolicy', + 'commentPolicy' => 'zot:commentPolicy', 'meData' => 'zot:meData', 'meDataType' => 'zot:meDataType', 'meEncoding' => 'zot:meEncoding', @@ -33,6 +33,9 @@ class Apschema extends \Zotlabs\Web\Controller { 'PropertyValue' => 'schema:PropertyValue', 'value' => 'schema:value', + 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', + + 'magicEnv' => [ '@id' => 'zot:magicEnv', '@type' => '@id' diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 4ebd2ee29..aebc70c15 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -95,6 +95,10 @@ class Channel extends Controller { http_status_exit(410, 'Gone'); } + if (get_pconfig($channel['channel_id'], 'system', 'index_opt_out')) { + App::$meta->set('robots', 'noindex, noarchive'); + } + if (ActivityStreams::is_as_request($channel)) { // Somebody may attempt an ActivityStreams fetch on one of our message permalinks diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php index 5025f4e22..b77e5d06d 100644 --- a/Zotlabs/Module/Connections.php +++ b/Zotlabs/Module/Connections.php @@ -2,32 +2,32 @@ namespace Zotlabs\Module; use App; +use Zotlabs\Lib\Permcat; require_once('include/socgraph.php'); require_once('include/selectors.php'); -require_once('include/group.php'); class Connections extends \Zotlabs\Web\Controller { function init() { - + if(! local_channel()) return; App::$profile_uid = local_channel(); - + $channel = App::get_channel(); if($channel) head_set_icon($channel['xchan_photo_s']); - + } - + function get() { - + $sort_type = 0; $o = ''; - - + + if(! local_channel()) { notice( t('Permission denied.') . EOL); return login(); @@ -44,13 +44,13 @@ class Connections extends \Zotlabs\Web\Controller { $pending = false; $unconnected = false; $all = false; - + if(! $_REQUEST['aj']) $_SESSION['return_url'] = App::$query_string; - + $search_flags = ""; $head = ''; - + if(argc() == 2) { switch(argv(1)) { case 'active': @@ -106,7 +106,7 @@ class Connections extends \Zotlabs\Web\Controller { // $head = t('Unconnected'); // $unconnected = true; // break; - + case 'all': $head = t('All'); break; @@ -115,19 +115,19 @@ class Connections extends \Zotlabs\Web\Controller { $active = true; $head = t('Active'); break; - + } - + $sql_extra = $search_flags; if(argv(1) === 'pending') $sql_extra .= " and abook_ignored = 0 "; - + } else { $sql_extra = " and abook_blocked = 0 "; $unblocked = true; } - + switch($_REQUEST['order']) { case 'name_desc': $sql_order = 'xchan_name DESC'; @@ -143,32 +143,32 @@ class Connections extends \Zotlabs\Web\Controller { } $search = ((x($_REQUEST,'search')) ? notags(trim($_REQUEST['search'])) : ''); - + $tabs = array( /* array( 'label' => t('Suggestions'), - 'url' => z_root() . '/suggest', + 'url' => z_root() . '/suggest', 'sel' => '', 'title' => t('Suggest new connections'), ), */ - + 'active' => array( 'label' => t('Active Connections'), - 'url' => z_root() . '/connections/active', + 'url' => z_root() . '/connections/active', 'sel' => ($active) ? 'active' : '', 'title' => t('Show active connections'), ), 'pending' => array( 'label' => t('New Connections'), - 'url' => z_root() . '/connections/pending', + 'url' => z_root() . '/connections/pending', 'sel' => ($pending) ? 'active' : '', 'title' => t('Show pending (new) connections'), ), - - + + /* array( 'label' => t('Unblocked'), @@ -177,55 +177,55 @@ class Connections extends \Zotlabs\Web\Controller { 'title' => t('Only show unblocked connections'), ), */ - + 'blocked' => array( 'label' => t('Blocked'), 'url' => z_root() . '/connections/blocked', 'sel' => ($blocked) ? 'active' : '', 'title' => t('Only show blocked connections'), ), - + 'ignored' => array( 'label' => t('Ignored'), 'url' => z_root() . '/connections/ignored', 'sel' => ($ignored) ? 'active' : '', 'title' => t('Only show ignored connections'), ), - + 'archived' => array( 'label' => t('Archived/Unreachable'), 'url' => z_root() . '/connections/archived', 'sel' => ($archived) ? 'active' : '', 'title' => t('Only show archived/unreachable connections'), ), - + 'hidden' => array( 'label' => t('Hidden'), 'url' => z_root() . '/connections/hidden', 'sel' => ($hidden) ? 'active' : '', 'title' => t('Only show hidden connections'), ), - + // array( // 'label' => t('Unconnected'), // 'url' => z_root() . '/connections/unconnected', // 'sel' => ($unconnected) ? 'active' : '', // 'title' => t('Only show one-way connections'), // ), - + 'all' => array( 'label' => t('All Connections'), - 'url' => z_root() . '/connections', + 'url' => z_root() . '/connections', 'sel' => ($all) ? 'active' : '', 'title' => t('Show all connections'), ), - + ); - + //$tab_tpl = get_markup_template('common_tabs.tpl'); //$t = replace_macros($tab_tpl, array('$tabs'=>$tabs)); - + $searching = false; if($search) { $search_hdr = $search; @@ -233,12 +233,12 @@ class Connections extends \Zotlabs\Web\Controller { $searching = true; } $sql_extra .= (($searching) ? protect_sprintf(" AND xchan_name like '%$search_txt%' ") : ""); - + if($_REQUEST['gid']) { $sql_extra .= " and xchan_hash in ( select xchan from pgrp_member where gid = " . intval($_REQUEST['gid']) . " and uid = " . intval(local_channel()) . " ) "; } - - $r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash + + $r = q("SELECT COUNT(abook.abook_id) AS total FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ", intval(local_channel()) ); @@ -246,19 +246,27 @@ class Connections extends \Zotlabs\Web\Controller { App::set_pager_total($r[0]['total']); $total = $r[0]['total']; } - + $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d and abook_self = 0 and xchan_deleted = 0 and xchan_orphan = 0 $sql_extra ORDER BY $sql_order LIMIT %d OFFSET %d ", intval(local_channel()), intval(App::$pager['itemspage']), intval(App::$pager['start']) ); - + + $roles = new Permcat(local_channel()); + $roles_list = $roles->listing(); + $roles_dict = []; + + foreach ($roles_list as $role) { + $roles_dict[$role['name']] = $role['localname']; + } + $contacts = array(); - + if($r) { - vcard_query($r); + //vcard_query($r); foreach($r as $rr) { @@ -268,7 +276,7 @@ class Connections extends \Zotlabs\Web\Controller { $phone = $rr['vcard']['tels'][0]['nr']; else $phone = ''; - + $status_str = ''; $status = array( ((intval($rr['abook_active'])) ? t('Active') : ''), @@ -306,7 +314,7 @@ class Connections extends \Zotlabs\Web\Controller { $perminfo['connperms'] .= t('Nothing'); } - + foreach($status as $str) { if(!$str) continue; @@ -314,14 +322,14 @@ class Connections extends \Zotlabs\Web\Controller { $status_str .= ', '; } $status_str = rtrim($status_str, ', '); - + $contacts[] = array( 'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']), 'edit_hover' => t('Edit connection'), 'edit' => t('Edit'), 'delete_hover' => t('Delete connection'), 'id' => $rr['abook_id'], - 'thumb' => $rr['xchan_photo_m'], + 'thumb' => $rr['xchan_photo_m'], 'name' => $rr['xchan_name'], 'classes' => ((intval($rr['abook_archived']) || intval($rr['abook_not_here'])) ? 'archived' : ''), 'link' => z_root() . '/connedit/' . $rr['abook_id'], @@ -349,13 +357,21 @@ class Connections extends \Zotlabs\Web\Controller { 'perminfo' => $perminfo, 'connect' => (intval($rr['abook_not_here']) ? t('Connect') : ''), 'follow' => z_root() . '/follow/?f=&url=' . urlencode($rr['xchan_hash']) . '&interactive=0', - 'connect_hover' => t('Connect at this location') + 'connect_hover' => t('Connect at this location'), + 'role' => $roles_dict[$rr['abook_role']] ); } } } - - + + $limit = service_class_fetch(local_channel(),'total_channels'); + if($limit !== false) { + $abook_usage_message = sprintf( t("You have %1$.0f of %2$.0f allowed connections."), $$total, $limit); + } + else { + $abook_usage_message = ''; + } + if($_REQUEST['aj']) { if($contacts) { $o = replace_macros(get_markup_template('contactsajax.tpl'),array( @@ -371,27 +387,29 @@ class Connections extends \Zotlabs\Web\Controller { } else { $o .= ""; - $o .= replace_macros(get_markup_template('connections.tpl'),array( + $o .= replace_macros(get_markup_template('connections.tpl'), [ '$header' => t('Connections') . (($head) ? ': ' . $head : ''), '$tabs' => $tabs, '$total' => $total, '$search' => $search_hdr, '$label' => t('Search'), + '$role_label' => t('Contact role'), '$desc' => t('Search your connections'), - '$finding' => (($searching) ? t('Connections search') . ": '" . $search . "'" : ""), + '$finding' => (($searching) ? t('Contact search') . ": '" . $search . "'" : ""), '$submit' => t('Find'), '$edit' => t('Edit'), '$cmd' => App::$cmd, '$contacts' => $contacts, '$paginate' => paginate($a), - - )); + '$abook_usage_message' => $abook_usage_message, + '$group_label' => t('This is a group/forum channel') + ]); } - + if(! $contacts) $o .= '
'; - + return $o; } - + } diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php index 7fabf1224..6bebef026 100644 --- a/Zotlabs/Module/Connedit.php +++ b/Zotlabs/Module/Connedit.php @@ -1,4 +1,5 @@ = 2) && intval(argv(1))) { + if ((argc() >= 2) && intval(argv(1))) { $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d and abook_id = %d and xchan_deleted = 0 LIMIT 1", + WHERE abook_channel = %d and abook_id = %d and abook_self = 0 and xchan_deleted = 0 LIMIT 1", intval(local_channel()), intval(argv(1)) ); - if($r) { + if ($r) { App::$poi = $r[0]; } } - $channel = App::get_channel(); - if($channel) + if ($channel) { head_set_icon($channel['xchan_photo_s']); - + } } @@ -63,188 +62,98 @@ class Connedit extends Controller { function post() { - if(! local_channel()) + if (!local_channel()) return; $contact_id = intval(argv(1)); - if(! $contact_id) + if (!$contact_id) return; $channel = App::get_channel(); - // TODO if configured for hassle-free permissions, we'll post the form with ajax as soon as the - // connection enable is toggled to a special autopost url and set permissions immediately, leaving - // the other form elements alone pending a manual submit of the form. The downside is that there - // will be a window of opportunity when the permissions have been set but before you've had a chance - // to review and possibly restrict them. The upside is we won't have to warn you that your connection - // can't do anything until you save the bloody form. - - $autopost = (((argc() > 2) && (argv(2) === 'auto')) ? true : false); - - $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", + $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d AND abook_self = 0 LIMIT 1", intval($contact_id), intval(local_channel()) ); - if(! $orig_record) { - notice( t('Could not access contact record.') . EOL); + if (!$orig_record) { + notice(t('Could not access contact record.') . EOL); goaway(z_root() . '/connections'); return; // NOTREACHED } call_hooks('contact_edit_post', $_POST); - $vc = get_abconfig(local_channel(),$orig_record['abook_xchan'],'system','vcard'); - $vcard = (($vc) ? \Sabre\VObject\Reader::read($vc) : null); - $serialised_vcard = update_vcard($_REQUEST,$vcard); - if($serialised_vcard) - set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'system','vcard',$serialised_vcard); - - if(intval($orig_record[0]['abook_self'])) { - $autoperms = intval($_POST['autoperms']); - $is_self = true; - } - else { - $autoperms = null; - $is_self = false; - } + $vc = get_abconfig(local_channel(), $orig_record['abook_xchan'], 'system', 'vcard'); + $vcard = (($vc) ? Reader::read($vc) : null); + $serialised_vcard = update_vcard($_REQUEST, $vcard); + if ($serialised_vcard) + set_abconfig(local_channel(), $orig_record[0]['abook_xchan'], 'system', 'vcard', $serialised_vcard); + $profile_id = ((array_key_exists('profile_assign', $_POST)) ? $_POST['profile_assign'] : $orig_record[0]['abook_profile']); - $profile_id = ((array_key_exists('profile_assign',$_POST)) ? $_POST['profile_assign'] : $orig_record[0]['abook_profile']); - - if($profile_id) { + if ($profile_id) { $r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND uid = %d LIMIT 1", dbesc($profile_id), intval(local_channel()) ); - if(! count($r)) { - notice( t('Could not locate selected profile.') . EOL); + if (!count($r)) { + notice(t('Could not locate selected profile.') . EOL); return; } } - $abook_incl = ((array_key_exists('abook_incl',$_POST)) ? escape_tags($_POST['abook_incl']) : $orig_record[0]['abook_incl']); - $abook_excl = ((array_key_exists('abook_excl',$_POST)) ? escape_tags($_POST['abook_excl']) : $orig_record[0]['abook_excl']); - - - $hidden = intval($_POST['hidden']); + $abook_incl = ((array_key_exists('abook_incl', $_POST)) ? escape_tags($_POST['abook_incl']) : $orig_record[0]['abook_incl']); + $abook_excl = ((array_key_exists('abook_excl', $_POST)) ? escape_tags($_POST['abook_excl']) : $orig_record[0]['abook_excl']); + $abook_role = ((array_key_exists('permcat', $_POST)) ? escape_tags($_POST['permcat']) : $orig_record[0]['abook_role']); - $priority = intval($_POST['poll']); - if($priority > 5 || $priority < 0) - $priority = 0; - - if(! array_key_exists('closeness',$_POST)) { + if (!array_key_exists('closeness', $_POST)) { $_POST['closeness'] = 80; } $closeness = intval($_POST['closeness']); - if($closeness < 0 || $closeness > 99) { + if ($closeness < 0 || $closeness > 99) { $closeness = 80; } - $rating = intval($_POST['rating']); - if($rating < (-10)) - $rating = (-10); - if($rating > 10) - $rating = 10; - - $rating_text = trim(escape_tags($_REQUEST['rating_text'])); + $new_friend = ((intval($orig_record[0]['abook_pending'])) ? true : false); - $all_perms = Permissions::Perms(); +/* + $perms = []; + $permcats = new Permcat(local_channel()); + $role_perms = $permcats->fetch($abook_role); + $all_perms = Permissions::Perms(); - if($all_perms) { - foreach($all_perms as $perm => $desc) { - if(array_key_exists('perms_' . $perm, $_POST)) { - set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm, - intval($_POST['perms_' . $perm])); - if($autoperms) { - set_pconfig($channel['channel_id'],'autoperms',$perm,intval($_POST['perms_' . $perm])); - } - } - else { - set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$perm,0); - if($autoperms) { - set_pconfig($channel['channel_id'],'autoperms',$perm,0); - } - } - } + // if we got a valid role use the role (default behaviour because a role is mandatory since version 7.0) + if (!isset($role_perms['error'])) { + $perms = $role_perms['raw_perms']; + if (intval($orig_record[0]['abook_pending'])) + $new_friend = true; } - if(! is_null($autoperms)) - set_pconfig($channel['channel_id'],'system','autoperms',$autoperms); - - $new_friend = false; - - // only store a record and notify the directory if the rating changed - - if(! $is_self) { - - $signed = $orig_record[0]['abook_xchan'] . '.' . $rating . '.' . $rating_text; - $sig = base64url_encode(Crypto::sign($signed,$channel['channel_prvkey'])); - - $rated = ((intval($rating) || strlen($rating_text)) ? true : false); - - $record = 0; - - $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", - dbesc($channel['channel_hash']), - dbesc($orig_record[0]['abook_xchan']) - ); - - if($z) { - if(($z[0]['xlink_rating'] != $rating) || ($z[0]['xlink_rating_text'] != $rating_text)) { - $record = $z[0]['xlink_id']; - $w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s' - where xlink_id = %d", - intval($rating), - dbesc($rating_text), - dbesc($sig), - dbesc(datetime_convert()), - intval($record) - ); - } - } - elseif($rated) { - // only create a record if there's something to save - $w = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ", - dbesc($channel['channel_hash']), - dbesc($orig_record[0]['abook_xchan']), - intval($rating), - dbesc($rating_text), - dbesc($sig), - dbesc(datetime_convert()) - ); - $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", - dbesc($channel['channel_hash']), - dbesc($orig_record[0]['abook_xchan']) - ); - if($z) - $record = $z[0]['xlink_id']; - } - } - - if(($_REQUEST['pending']) && intval($orig_record[0]['abook_pending'])) { - + // approve shortcut (no role provided) + if (!$perms && intval($orig_record[0]['abook_pending'])) { + $connect_perms = Permissions::connect_perms(local_channel()); + $perms = $connect_perms['perms']; + // set the role from $connect_perms + $abook_role = $connect_perms['role']; $new_friend = true; + } - // @fixme it won't be common, but when you accept a new connection request - // the permissions will now be that of your permissions role and ignore - // any you may have set manually on the form. We'll probably see a bug if somebody - // tries to set the permissions *and* approve the connection in the same - // request. The workaround is to approve the connection, then go back and - // adjust permissions as desired. - - $p = Permissions::connect_perms(local_channel()); - $my_perms = $p['perms']; - if($my_perms) { - foreach($my_perms as $k => $v) { - set_abconfig($channel['channel_id'],$orig_record[0]['abook_xchan'],'my_perms',$k,$v); + if ($all_perms && $perms) { + foreach ($all_perms as $perm => $desc) { + if (array_key_exists($perm, $perms)) { + set_abconfig($channel['channel_id'], $orig_record[0]['abook_xchan'], 'my_perms', $perm, intval($perms[$perm])); + } + else { + set_abconfig($channel['channel_id'], $orig_record[0]['abook_xchan'], 'my_perms', $perm, 0); } } } +*/ - $abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']); - + \Zotlabs\Lib\Permcat::assign($channel, $abook_role, [$orig_record[0]['abook_xchan']]); + $abook_pending = (($new_friend) ? 0 : $orig_record[0]['abook_pending']); $r = q("UPDATE abook SET abook_profile = '%s', abook_closeness = %d, abook_pending = %d, abook_incl = '%s', abook_excl = '%s' @@ -258,30 +167,29 @@ class Connedit extends Controller { intval(local_channel()) ); - if($r) - info( t('Connection updated.') . EOL); + if ($r) + info(t('Connection updated.') . EOL); else - notice( t('Failed to update connection record.') . EOL); + notice(t('Failed to update connection record.') . EOL); - if(! intval(App::$poi['abook_self'])) { - if($new_friend) { - Master::Summon( [ 'Notifier', 'permission_accept', $contact_id ] ); + if (!intval(App::$poi['abook_self'])) { + if ($new_friend) { + Master::Summon(['Notifier', 'permission_accept', $contact_id]); } - Master::Summon( [ + Master::Summon([ 'Notifier', (($new_friend) ? 'permission_create' : 'permission_update'), $contact_id ]); } - if($new_friend) { + if ($new_friend) { $default_group = $channel['channel_default_group']; - if($default_group) { - require_once('include/group.php'); - $g = group_rec_byhash(local_channel(),$default_group); - if($g) - group_add_member(local_channel(),'',App::$poi['abook_xchan'],$g['id']); + if ($default_group) { + $g = AccessList::by_hash(local_channel(), $default_group); + if ($g) + AccessList::member_add(local_channel(), '', App::$poi['abook_xchan'], $g['id']); } // Check if settings permit ("post new friend activity" is allowed, and @@ -291,18 +199,18 @@ class Connedit extends Controller { $pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0", intval($channel['channel_id']) ); - if(($pr) && (! intval($orig_record[0]['abook_hidden'])) && (intval(get_pconfig($channel['channel_id'],'system','post_newfriend')))) { + if (($pr) && (!intval($orig_record[0]['abook_hidden'])) && (intval(get_pconfig($channel['channel_id'], 'system', 'post_newfriend')))) { $xarr = []; - $xarr['item_wall'] = 1; - $xarr['item_origin'] = 1; + $xarr['item_wall'] = 1; + $xarr['item_origin'] = 1; $xarr['item_thread_top'] = 1; - $xarr['owner_xchan'] = $xarr['author_xchan'] = $channel['channel_hash']; - $xarr['allow_cid'] = $channel['channel_allow_cid']; - $xarr['allow_gid'] = $channel['channel_allow_gid']; - $xarr['deny_cid'] = $channel['channel_deny_cid']; - $xarr['deny_gid'] = $channel['channel_deny_gid']; - $xarr['item_private'] = (($xarr['allow_cid']||$xarr['allow_gid']||$xarr['deny_cid']||$xarr['deny_gid']) ? 1 : 0); + $xarr['owner_xchan'] = $xarr['author_xchan'] = $channel['channel_hash']; + $xarr['allow_cid'] = $channel['channel_allow_cid']; + $xarr['allow_gid'] = $channel['channel_allow_gid']; + $xarr['deny_cid'] = $channel['channel_deny_cid']; + $xarr['deny_gid'] = $channel['channel_deny_gid']; + $xarr['item_private'] = (($xarr['allow_cid'] || $xarr['allow_gid'] || $xarr['deny_cid'] || $xarr['deny_gid']) ? 1 : 0); $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . App::$poi['xchan_url'] . ']' . App::$poi['xchan_name'] . '[/zrl]'; @@ -312,9 +220,8 @@ class Connedit extends Controller { } - // pull in a bit of content if there is any to pull in - Master::Summon(array('Onepoll',$contact_id)); + Master::Summon(['Onepoll', $contact_id]); } @@ -326,18 +233,18 @@ class Connedit extends Controller { intval(local_channel()), intval($contact_id) ); - if($r) { + if ($r) { App::$poi = $r[0]; } - if($new_friend) { - $arr = array('channel_id' => local_channel(), 'abook' => App::$poi); + if ($new_friend) { + $arr = ['channel_id' => local_channel(), 'abook' => App::$poi]; call_hooks('accept_follow', $arr); } - $this->connedit_clone($a); + $this->connedit_clone(); - if(($_REQUEST['pending']) && (!$_REQUEST['done'])) + if (($_REQUEST['pending']) && (!$_REQUEST['done'])) goaway(z_root() . '/connections/ifpending'); return; @@ -349,35 +256,34 @@ class Connedit extends Controller { * */ - function connedit_clone(&$a) { - - if(! App::$poi) - return; + function connedit_clone() { + if (!App::$poi) + return; - $channel = App::get_channel(); + $channel = App::get_channel(); - $r = q("SELECT abook.*, xchan.* + $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d and abook_id = %d LIMIT 1", - intval(local_channel()), - intval(App::$poi['abook_id']) - ); - if($r) { - App::$poi = array_shift($r); - } + intval(local_channel()), + intval(App::$poi['abook_id']) + ); + if ($r) { + App::$poi = $r[0]; + } - $clone = App::$poi; + $clone = App::$poi; - unset($clone['abook_id']); - unset($clone['abook_account']); - unset($clone['abook_channel']); + unset($clone['abook_id']); + unset($clone['abook_account']); + unset($clone['abook_channel']); - $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); - if($abconfig) - $clone['abconfig'] = $abconfig; + $abconfig = load_abconfig($channel['channel_id'], $clone['abook_xchan']); + if ($abconfig) + $clone['abconfig'] = $abconfig; - Libsync::build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone))); + Libsync::build_sync_packet(0 /* use the current local_channel */, ['abook' => [$clone]]); } /* @brief Generate content of connection edit page @@ -387,37 +293,19 @@ class Connedit extends Controller { function get() { - $sort_type = 0; $o = ''; - if(! local_channel()) { - notice( t('Permission denied.') . EOL); + if (!local_channel()) { + notice(t('Permission denied.') . EOL); return login(); } - $section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : ''); - $channel = App::get_channel(); - - $yes_no = array(t('No'),t('Yes')); - - $connect_perms = Permissions::connect_perms(local_channel()); - - $o .= "\n"; + $section = ((array_key_exists('section', $_REQUEST)) ? $_REQUEST['section'] : ''); - if(argc() == 3) { + if (argc() == 3) { $contact_id = intval(argv(1)); - if(! $contact_id) + if (!$contact_id) return; $cmd = argv(2); @@ -428,35 +316,35 @@ class Connedit extends Controller { intval(local_channel()) ); - if(! count($orig_record)) { - notice( t('Could not access address book record.') . EOL); + if (!count($orig_record)) { + notice(t('Could not access address book record.') . EOL); goaway(z_root() . '/connections'); } - if($cmd === 'update') { + if ($cmd === 'update') { // pull feed and consume it, which should subscribe to the hub. - Master::Summon(array('Poller',$contact_id)); + Master::Summon(['Poller', $contact_id]); goaway(z_root() . '/connedit/' . $contact_id); } - if($cmd === 'fetchvc') { - $url = str_replace('/channel/','/profile/',$orig_record[0]['xchan_url']) . '/vcard'; + if ($cmd === 'fetchvc') { + $url = str_replace('/channel/', '/profile/', $orig_record[0]['xchan_url']) . '/vcard'; $recurse = 0; - $x = z_fetch_url(zid($url),false,$recurse,['session' => true]); - if($x['success']) { - $h = new HTTPHeaders($x['header']); + $x = z_fetch_url(zid($url), false, $recurse, ['session' => true]); + if ($x['success']) { + $h = new HTTPHeaders($x['header']); $fields = $h->fetch(); - if($fields) { - foreach($fields as $y) { - if(array_key_exists('content-type',$y)) { - $type = explode(';',trim($y['content-type'])); - if($type && $type[0] === 'text/vcard' && $x['body']) { - $vc = \Sabre\VObject\Reader::read($x['body']); + if ($fields) { + foreach ($fields as $y) { + if (array_key_exists('content-type', $y)) { + $type = explode(';', trim($y['content-type'])); + if ($type && $type[0] === 'text/vcard' && $x['body']) { + $vc = Reader::read($x['body']); $vcard = $vc->serialize(); - if($vcard) { - set_abconfig(local_channel(),$orig_record[0]['abook_xchan'],'system','vcard',$vcard); - $this->connedit_clone($a); + if ($vcard) { + set_abconfig(local_channel(), $orig_record[0]['abook_xchan'], 'system', 'vcard', $vcard); + $this->connedit_clone(); } } } @@ -467,55 +355,55 @@ class Connedit extends Controller { } - if($cmd === 'resetphoto') { + if ($cmd === 'resetphoto') { q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s'", dbesc($orig_record[0]['xchan_hash']) ); $cmd = 'refresh'; } - if($cmd === 'refresh') { - if($orig_record[0]['xchan_network'] === 'zot6') { - if(! Libzot::refresh($orig_record[0],App::get_channel())) - notice( t('Refresh failed - channel is currently unavailable.') ); + if ($cmd === 'refresh') { + if ($orig_record[0]['xchan_network'] === 'zot6') { + if (!Libzot::refresh($orig_record[0], App::get_channel())) + notice(t('Refresh failed - channel is currently unavailable.')); } else { // if you are on a different network we'll force a refresh of the connection basic info - Master::Summon(array('Notifier','permission_update',$contact_id)); + Master::Summon(['Notifier', 'permission_update', $contact_id]); } goaway(z_root() . '/connedit/' . $contact_id); } - if($cmd === 'block') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_BLOCKED)) { - $this->connedit_clone($a); + if ($cmd === 'block') { + if (abook_toggle_flag($orig_record[0], ABOOK_FLAG_BLOCKED)) { + $this->connedit_clone(); } else notice(t('Unable to set address book parameters.') . EOL); goaway(z_root() . '/connedit/' . $contact_id); } - if($cmd === 'ignore') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_IGNORED)) { - $this->connedit_clone($a); + if ($cmd === 'ignore') { + if (abook_toggle_flag($orig_record[0], ABOOK_FLAG_IGNORED)) { + $this->connedit_clone(); } else notice(t('Unable to set address book parameters.') . EOL); goaway(z_root() . '/connedit/' . $contact_id); } - if($cmd === 'archive') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_ARCHIVED)) { - $this->connedit_clone($a); + if ($cmd === 'archive') { + if (abook_toggle_flag($orig_record[0], ABOOK_FLAG_ARCHIVED)) { + $this->connedit_clone(); } else notice(t('Unable to set address book parameters.') . EOL); goaway(z_root() . '/connedit/' . $contact_id); } - if($cmd === 'hide') { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_HIDDEN)) { - $this->connedit_clone($a); + if ($cmd === 'hide') { + if (abook_toggle_flag($orig_record[0], ABOOK_FLAG_HIDDEN)) { + $this->connedit_clone(); } else notice(t('Unable to set address book parameters.') . EOL); @@ -525,10 +413,10 @@ class Connedit extends Controller { // We'll prevent somebody from unapproving an already approved contact. // Though maybe somebody will want this eventually (??) - if($cmd === 'approve') { - if(intval($orig_record[0]['abook_pending'])) { - if(abook_toggle_flag($orig_record[0],ABOOK_FLAG_PENDING)) { - $this->connedit_clone($a); + if ($cmd === 'approve') { + if (intval($orig_record[0]['abook_pending'])) { + if (abook_toggle_flag($orig_record[0], ABOOK_FLAG_PENDING)) { + $this->connedit_clone(); } else notice(t('Unable to set address book parameters.') . EOL); @@ -537,132 +425,130 @@ class Connedit extends Controller { } - if($cmd === 'drop') { + if ($cmd === 'drop') { contact_remove(local_channel(), $orig_record[0]['abook_id']); - Master::Summon( [ 'Notifier', 'purge', local_channel(), $orig_record[0]['xchan_hash'] ] ); + Master::Summon(['Notifier', 'purge', local_channel(), $orig_record[0]['xchan_hash']]); Libsync::build_sync_packet(0 /* use the current local_channel */, - array('abook' => array(array( - 'abook_xchan' => $orig_record[0]['abook_xchan'], - 'entry_deleted' => true)) - ) + ['abook' => [[ + 'abook_xchan' => $orig_record[0]['abook_xchan'], + 'entry_deleted' => true]] + ] ); - info( t('Connection has been removed.') . EOL ); - if(x($_SESSION,'return_url')) + info(t('Connection has been removed.') . EOL); + if (x($_SESSION, 'return_url')) goaway(z_root() . '/' . $_SESSION['return_url']); goaway(z_root() . '/contacts'); } } - if(App::$poi) { + if (App::$poi) { $abook_prev = 0; $abook_next = 0; - $contact_id = App::$poi['abook_id']; - $contact = App::$poi; + $contact = App::$poi; $cn = q("SELECT abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 order by xchan_name", intval(local_channel()) ); - if($cn) { + if ($cn) { $pntotal = count($cn); - for($x = 0; $x < $pntotal; $x ++) { - if($cn[$x]['abook_id'] == $contact_id) { - if($x === 0) + for ($x = 0; $x < $pntotal; $x++) { + if ($cn[$x]['abook_id'] == $contact_id) { + if ($x === 0) $abook_prev = 0; else $abook_prev = $cn[$x - 1]['abook_id']; - if($x === $pntotal) + if ($x === $pntotal) $abook_next = 0; else - $abook_next = $cn[$x +1]['abook_id']; + $abook_next = $cn[$x + 1]['abook_id']; } } - } + } - $tools = array( + $tools = [ - 'view' => array( + 'view' => [ 'label' => t('View Profile'), 'url' => chanlink_cid($contact['abook_id']), 'sel' => '', - 'title' => sprintf( t('View %s\'s profile'), $contact['xchan_name']), - ), + 'title' => sprintf(t('View %s\'s profile'), $contact['xchan_name']), + ], - 'refresh' => array( + 'refresh' => [ 'label' => t('Refresh Permissions'), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/refresh', 'sel' => '', 'title' => t('Fetch updated permissions'), - ), + ], - 'rephoto' => array( + 'rephoto' => [ 'label' => t('Refresh Photo'), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/resetphoto', 'sel' => '', 'title' => t('Fetch updated photo'), - ), + ], - 'recent' => array( + 'recent' => [ 'label' => t('Recent Activity'), 'url' => z_root() . '/network/?f=&cid=' . $contact['abook_id'], 'sel' => '', 'title' => t('View recent posts and comments'), - ), + ], - 'block' => array( + 'block' => [ 'label' => (intval($contact['abook_blocked']) ? t('Unblock') : t('Block')), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/block', 'sel' => (intval($contact['abook_blocked']) ? 'active' : ''), 'title' => t('Block (or Unblock) all communications with this connection'), - 'info' => (intval($contact['abook_blocked']) ? t('This connection is blocked!') : ''), - ), + 'info' => (intval($contact['abook_blocked']) ? t('This connection is blocked!') : ''), + ], - 'ignore' => array( + 'ignore' => [ 'label' => (intval($contact['abook_ignored']) ? t('Unignore') : t('Ignore')), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/ignore', 'sel' => (intval($contact['abook_ignored']) ? 'active' : ''), 'title' => t('Ignore (or Unignore) all inbound communications from this connection'), - 'info' => (intval($contact['abook_ignored']) ? t('This connection is ignored!') : ''), - ), + 'info' => (intval($contact['abook_ignored']) ? t('This connection is ignored!') : ''), + ], - 'archive' => array( + 'archive' => [ 'label' => (intval($contact['abook_archived']) ? t('Unarchive') : t('Archive')), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/archive', 'sel' => (intval($contact['abook_archived']) ? 'active' : ''), 'title' => t('Archive (or Unarchive) this connection - mark channel dead but keep content'), - 'info' => (intval($contact['abook_archived']) ? t('This connection is archived!') : ''), - ), + 'info' => (intval($contact['abook_archived']) ? t('This connection is archived!') : ''), + ], - 'hide' => array( + 'hide' => [ 'label' => (intval($contact['abook_hidden']) ? t('Unhide') : t('Hide')), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/hide', 'sel' => (intval($contact['abook_hidden']) ? 'active' : ''), 'title' => t('Hide or Unhide this connection from your other connections'), - 'info' => (intval($contact['abook_hidden']) ? t('This connection is hidden!') : ''), - ), + 'info' => (intval($contact['abook_hidden']) ? t('This connection is hidden!') : ''), + ], - 'delete' => array( + 'delete' => [ 'label' => t('Delete'), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/drop', 'sel' => '', 'title' => t('Delete this connection'), - ), - - ); + ], + ]; - if($contact['xchan_network'] === 'zot6') { + if ($contact['xchan_network'] === 'zot6') { $tools['fetchvc'] = [ 'label' => t('Fetch Vcard'), - 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/fetchvc', + 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/fetchvc', 'sel' => '', 'title' => t('Fetch electronic calling card for this connection') ]; @@ -671,31 +557,16 @@ class Connedit extends Controller { $sections = []; - $sections['perms'] = [ - 'label' => t('Permissions'), - 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=§ion=perms', - 'sel' => '', - 'title' => t('Open Individual Permissions section by default'), - ]; - - $self = false; - - if(intval($contact['abook_self'])) { - $self = true; - $abook_prev = $abook_next = 0; - } - - $vc = get_abconfig(local_channel(),$contact['abook_xchan'],'system','vcard'); + $vc = get_abconfig(local_channel(), $contact['abook_xchan'], 'system', 'vcard'); - $vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null); - $vcard = (($vctmp) ? get_vcard_array($vctmp,$contact['abook_id']) : [] ); - if(! $vcard) + $vctmp = (($vc) ? Reader::read($vc) : null); + $vcard = (($vctmp) ? get_vcard_array($vctmp, $contact['abook_id']) : []); + if (!$vcard['fn']) $vcard['fn'] = $contact['xchan_name']; - $tpl = get_markup_template("abook_edit.tpl"); - if(Apps::system_app_installed(local_channel(),'Affinity Tool')) { + if (Apps::system_app_installed(local_channel(), 'Affinity Tool')) { $sections['affinity'] = [ 'label' => t('Affinity'), @@ -711,12 +582,12 @@ class Connedit extends Controller { t('Acquaintances'), t('All') ]; - call_hooks('affinity_labels',$labels); + call_hooks('affinity_labels', $labels); $label_str = ''; - if($labels) { - foreach($labels as $l) { - if($label_str) { + if ($labels) { + foreach ($labels as $l) { + if ($label_str) { $label_str .= ", '|'"; $label_str .= ", '" . $l . "'"; } @@ -729,14 +600,14 @@ class Connedit extends Controller { $slideval = intval($contact['abook_closeness']); - $slide = replace_macros($slider_tpl,array( - '$min' => 1, - '$val' => $slideval, + $slide = replace_macros($slider_tpl, [ + '$min' => 1, + '$val' => $slideval, '$labels' => $label_str, - )); + ]); } - if(feature_enabled(local_channel(),'connfilter')) { + if (feature_enabled(local_channel(), 'connfilter')) { $sections['filter'] = [ 'label' => t('Filter'), 'url' => z_root() . '/connedit/' . $contact['abook_id'] . '/?f=§ion=filter', @@ -745,195 +616,148 @@ class Connedit extends Controller { ]; } - $rating_val = 0; - $rating_text = ''; - - $xl = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1", - dbesc($channel['channel_hash']), - dbesc($contact['xchan_hash']) - ); - - if($xl) { - $rating_val = intval($xl[0]['xlink_rating']); - $rating_text = $xl[0]['xlink_rating_text']; - } - - $rating_enabled = get_config('system','rating_enabled'); - - if($rating_enabled) { - $rating = replace_macros(get_markup_template('rating_slider.tpl'),array( - '$min' => -10, - '$val' => $rating_val - )); - } - else { - $rating = false; - } - - - $perms = array(); - $channel = App::get_channel(); - + $perms = []; $global_perms = Permissions::Perms(); + $existing = get_all_perms(local_channel(), $contact['abook_xchan'], false); + $unapproved = ['pending', t('Approve this contact'), '', t('Accept contact to allow communication'), [t('No'), ('Yes')]]; + $multiprofs = ((feature_enabled(local_channel(), 'multi_profiles')) ? true : false); - $existing = get_all_perms(local_channel(),$contact['abook_xchan'],false); - - $unapproved = array('pending', t('Approve this connection'), '', t('Accept connection to allow communication'), array(t('No'),('Yes'))); - - $multiprofs = ((feature_enabled(local_channel(),'multi_profiles')) ? true : false); - - if($slide && !$multiprofs) + if ($slide && !$multiprofs) $affinity = t('Set Affinity'); - if(!$slide && $multiprofs) + if (!$slide && $multiprofs) $affinity = t('Set Profile'); - if($slide && $multiprofs) + if ($slide && $multiprofs) $affinity = t('Set Affinity & Profile'); $theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'", - intval(local_channel()), - dbesc($contact['abook_xchan']) + intval(local_channel()), + dbesc($contact['abook_xchan']) ); - $their_perms = array(); - if($theirs) { - foreach($theirs as $t) { + + $their_perms = []; + if ($theirs) { + foreach ($theirs as $t) { $their_perms[$t['k']] = $t['v']; } } - foreach($global_perms as $k => $v) { - $thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k); -//fixme - - $checkinherited = PermissionLimits::Get(local_channel(),$k); - - // For auto permissions (when $self is true) we don't want to look at existing - // permissions because they are enabled for the channel owner - if((! $self) && ($existing[$k])) - $thisperm = "1"; - - + foreach ($global_perms as $k => $v) { + $thisperm = $existing[$k]; + $checkinherited = PermissionLimits::Get(local_channel(), $k); + $perms[] = ['perms_' . $k, $v, ((array_key_exists($k, $their_perms)) ? intval($their_perms[$k]) : ''), $thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '0' : '1'), '', $checkinherited]; + } + $pcat = new Permcat(local_channel()); + $pcatlist = $pcat->listing(); + $default_role = get_pconfig(local_channel(), 'system', 'default_permcat'); + $current_permcat = (($contact['abook_pending']) ? $default_role : $contact['abook_role']); - $perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited); + if (!$current_permcat) { + notice(t('Please select a role for this contact!') . EOL); + $permcats[] = ''; } - $pcat = new Permcat(local_channel()); - $pcatlist = $pcat->listing(); - $permcats = []; - if($pcatlist) { - foreach($pcatlist as $pc) { + if ($pcatlist) { + foreach ($pcatlist as $pc) { $permcats[$pc['name']] = $pc['localname']; } } $locstr = locations_by_netid($contact['xchan_hash']); - if(! $locstr) + if (!$locstr) { $locstr = unpunify($contact['xchan_url']); + } $clone_warn = ''; - $clonable = in_array($contact['xchan_network'], ['zot6', 'rss']); - if(! $clonable) { + $clonable = in_array($contact['xchan_network'], ['zot6', 'rss']); + if (!$clonable) { $clone_warn = ''; $clone_warn .= ((intval($contact['abook_not_here'])) - ? t('This connection is unreachable from this location.') - : t('This connection may be unreachable from other channel locations.') + ? t('This contact is unreachable from this location.') + : t('This contact may be unreachable from other channel locations.') ); $clone_warn .= '
' . t('Location independence is not supported by their network.'); } - - - if(intval($contact['abook_not_here']) && $unclonable) - $not_here = t('This connection is unreachable from this location. Location independence is not supported by their network.'); - $o .= replace_macros($tpl, [ - '$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])), - '$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no), - '$permcat' => [ 'permcat', t('Permission role'), '', '',$permcats ], - '$permcat_new' => t('Add permission role'), - '$permcat_enable' => Apps::system_app_installed(local_channel(), 'Permission Categories'), - '$addr' => unpunify($contact['xchan_addr']), - '$primeurl' => unpunify($contact['xchan_url']), - '$section' => $section, - '$sections' => $sections, - '$vcard' => $vcard, - '$addr_text' => t('This connection\'s primary address is'), - '$loc_text' => t('Available locations:'), - '$locstr' => $locstr, - '$unclonable' => $clone_warn, - '$notself' => (($self) ? '' : '1'), - '$self' => (($self) ? '1' : ''), - '$autolbl' => t('The permissions indicated on this page will be applied to all new connections.'), - '$tools_label' => t('Connection Tools'), - '$tools' => (($self) ? '' : $tools), - '$lbl_slider' => t('Slide to adjust your degree of friendship'), - '$lbl_rating' => t('Rating'), - '$lbl_rating_label' => t('Slide to adjust your rating'), - '$lbl_rating_txt' => t('Optionally explain your rating'), - '$connfilter' => feature_enabled(local_channel(),'connfilter'), + '$header' => sprintf(t('Contact: %s'), $contact['xchan_name']), + '$permcat' => ['permcat', t('Contact role'), $current_permcat, '', $permcats], + '$permcat_new' => t('Manage contact roles'), + '$permcat_value' => bin2hex($current_permcat), + '$addr' => unpunify($contact['xchan_addr']), + '$primeurl' => unpunify($contact['xchan_url']), + '$section' => $section, + '$sections' => $sections, + '$vcard' => $vcard, + '$addr_text' => t('This contacts\'s primary address is'), + '$loc_text' => t('Available locations:'), + '$locstr' => $locstr, + '$unclonable' => $clone_warn, + '$notself' => '1', + '$self' => '', + '$autolbl' => t('The permissions indicated on this page will be applied to all new connections.'), + '$tools_label' => t('Contact Tools'), + '$tools' => $tools, + '$lbl_slider' => t('Slide to adjust your degree of friendship'), + '$connfilter' => feature_enabled(local_channel(), 'connfilter'), '$connfilter_label' => t('Custom Filter'), - '$incl' => array('abook_incl',t('Only import posts with this text'), $contact['abook_incl'],t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')), - '$excl' => array('abook_excl',t('Do not import posts with this text'), $contact['abook_excl'],t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')), - '$rating_text' => array('rating_text', t('Optionally explain your rating'),$rating_text,''), - '$rating_info' => t('This information is public!'), - '$rating' => $rating, - '$rating_val' => $rating_val, - '$slide' => $slide, - '$affinity' => $affinity, - '$pending_label' => t('Connection Pending Approval'), - '$is_pending' => (intval($contact['abook_pending']) ? 1 : ''), - '$unapproved' => $unapproved, - '$inherited' => t('inherited'), - '$submit' => t('Submit'), - '$lbl_vis2' => sprintf( t('Please choose the profile you would like to display to %s when viewing your profile securely.'), $contact['xchan_name']), - '$close' => (($contact['abook_closeness']) ? $contact['abook_closeness'] : 80), - '$them' => t('Their Settings'), - '$me' => t('My Settings'), - '$perms' => $perms, - '$permlbl' => t('Individual Permissions'), - '$permnote' => t('Some permissions may be inherited from your channel\'s privacy settings, which have higher priority than individual settings. You can not change those settings here.'), - '$permnote_self' => t('Some permissions may be inherited from your channel\'s privacy settings, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'), - '$lastupdtext' => t('Last update:'), - '$last_update' => relative_date($contact['abook_connected']), - '$profile_select' => contact_profile_assign($contact['abook_profile']), - '$multiprofs' => $multiprofs, - '$contact_id' => $contact['abook_id'], - '$name' => $contact['xchan_name'], - '$abook_prev' => $abook_prev, - '$abook_next' => $abook_next, - '$vcard_label' => t('Details'), - '$displayname' => $displayname, - '$name_label' => t('Name'), - '$org_label' => t('Organisation'), - '$title_label' => t('Title'), - '$tel_label' => t('Phone'), - '$email_label' => t('Email'), - '$impp_label' => t('Instant messenger'), - '$url_label' => t('Website'), - '$adr_label' => t('Address'), - '$note_label' => t('Note'), - '$mobile' => t('Mobile'), - '$home' => t('Home'), - '$work' => t('Work'), - '$other' => t('Other'), - '$add_card' => t('Add Contact'), - '$add_field' => t('Add Field'), - '$create' => t('Create'), - '$update' => t('Update'), - '$delete' => t('Delete'), - '$cancel' => t('Cancel'), - '$po_box' => t('P.O. Box'), - '$extra' => t('Additional'), - '$street' => t('Street'), - '$locality' => t('Locality'), - '$region' => t('Region'), - '$zip_code' => t('ZIP Code'), - '$country' => t('Country') + '$incl' => ['abook_incl', t('Only import posts with this text'), $contact['abook_incl'], t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')], + '$excl' => ['abook_excl', t('Do not import posts with this text'), $contact['abook_excl'], t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')], + '$slide' => $slide, + '$affinity' => $affinity, + '$pending_label' => t('Contact Pending Approval'), + '$is_pending' => (intval($contact['abook_pending']) ? 1 : ''), + '$unapproved' => $unapproved, + '$inherited' => t('inherited'), + '$submit' => ((intval($contact['abook_pending'])) ? t('Approve contact') : t('Submit')), + '$lbl_vis2' => sprintf(t('Please choose the profile you would like to display to %s when viewing your profile securely.'), $contact['xchan_name']), + '$close' => (($contact['abook_closeness']) ? $contact['abook_closeness'] : 80), + '$them' => t('Their'), + '$me' => t('My'), + '$perms' => $perms, + '$permlbl' => t('Individual Permissions'), + '$permnote' => t('Some permissions may be inherited from your channel\'s privacy settings, which have higher priority than individual settings. You can not change those settings here.'), + '$permnote_self' => t('Some permissions may be inherited from your channel\'s privacy settings, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'), + '$lastupdtext' => t('Last update:'), + '$last_update' => relative_date($contact['abook_connected']), + '$profile_select' => contact_profile_assign($contact['abook_profile']), + '$multiprofs' => $multiprofs, + '$contact_id' => $contact['abook_id'], + '$name' => $contact['xchan_name'], + '$abook_prev' => $abook_prev, + '$abook_next' => $abook_next, + '$vcard_label' => t('Details'), + '$name_label' => t('Name'), + '$org_label' => t('Organisation'), + '$title_label' => t('Title'), + '$tel_label' => t('Phone'), + '$email_label' => t('Email'), + '$impp_label' => t('Instant messenger'), + '$url_label' => t('Website'), + '$adr_label' => t('Address'), + '$note_label' => t('Note'), + '$mobile' => t('Mobile'), + '$home' => t('Home'), + '$work' => t('Work'), + '$other' => t('Other'), + '$add_card' => t('Add Contact'), + '$add_field' => t('Add Field'), + '$create' => t('Create'), + '$update' => t('Update'), + '$delete' => t('Delete'), + '$cancel' => t('Cancel'), + '$po_box' => t('P.O. Box'), + '$extra' => t('Additional'), + '$street' => t('Street'), + '$locality' => t('Locality'), + '$region' => t('Region'), + '$zip_code' => t('ZIP Code'), + '$country' => t('Country') ]); - $arr = array('contact' => $contact,'output' => $o); + $arr = ['contact' => $contact, 'output' => $o]; call_hooks('contact_edit', $arr); diff --git a/Zotlabs/Module/Contactedit.php b/Zotlabs/Module/Contactedit.php new file mode 100644 index 000000000..b09b5b1ec --- /dev/null +++ b/Zotlabs/Module/Contactedit.php @@ -0,0 +1,668 @@ += 2) && intval(argv(1))) { + $r = q("SELECT abook.*, xchan.* FROM abook LEFT JOIN xchan ON abook_xchan = xchan_hash + WHERE abook_channel = %d AND abook_id = %d AND abook_self = 0 AND xchan_deleted = 0", + intval(local_channel()), + intval(argv(1)) + ); + if (!$r) { + json_return_and_die([ + 'success' => false, + 'message' => t('Invalid abook_id') + ]); + } + + App::$poi = $r[0]; + + } + } + + + /* @brief Evaluate posted values and set changes + * + */ + + function post() { + + if (!local_channel()) + return; + + $contact_id = intval(argv(1)); + if (!$contact_id) + return; + + $channel = App::get_channel(); + + $contact = App::$poi; + + if (!$contact) { + notice(t('Could not access contact record.') . EOL); + killme(); + } + + call_hooks('contact_edit_post', $_REQUEST); + + if (Apps::system_app_installed(local_channel(), 'Privacy Groups')) { + $pgrp_ids = q("SELECT id FROM pgrp WHERE deleted = 0 AND uid = %d", + intval(local_channel()) + ); + + foreach($pgrp_ids as $pgrp) { + if (array_key_exists('pgrp_id_' . $pgrp['id'], $_REQUEST)) { + AccessList::member_add(local_channel(), '', $contact['abook_xchan'], $pgrp['id']); + } + else { + AccessList::member_remove(local_channel(), '', $contact['abook_xchan'], $pgrp['id']); + } + } + } + + $profile_id = ((array_key_exists('profile_assign', $_REQUEST)) ? $_REQUEST['profile_assign'] : $contact['abook_profile']); + + if ($profile_id) { + $r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND uid = %d LIMIT 1", + dbesc($profile_id), + intval(local_channel()) + ); + if (!count($r)) { + notice(t('Could not locate selected profile.') . EOL); + return; + } + } + + $abook_incl = ((array_key_exists('abook_incl', $_REQUEST)) ? escape_tags($_REQUEST['abook_incl']) : $contact['abook_incl']); + $abook_excl = ((array_key_exists('abook_excl', $_REQUEST)) ? escape_tags($_REQUEST['abook_excl']) : $contact['abook_excl']); + $abook_role = ((array_key_exists('permcat', $_REQUEST)) ? escape_tags($_REQUEST['permcat']) : $contact['abook_role']); + + if (!array_key_exists('closeness', $_REQUEST)) { + $_REQUEST['closeness'] = 80; + } + + $closeness = intval($_REQUEST['closeness']); + + if ($closeness < 0 || $closeness > 99) { + $closeness = 80; + } + + $new_friend = ((intval($contact['abook_pending'])) ? true : false); + + \Zotlabs\Lib\Permcat::assign($channel, $abook_role, [$contact['abook_xchan']]); + + $abook_pending = (($new_friend) ? 0 : $contact['abook_pending']); + + $r = q("UPDATE abook SET abook_profile = '%s', abook_closeness = %d, abook_pending = %d, + abook_incl = '%s', abook_excl = '%s' + where abook_id = %d AND abook_channel = %d", + dbesc($profile_id), + intval($closeness), + intval($abook_pending), + dbesc($abook_incl), + dbesc($abook_excl), + intval($contact_id), + intval(local_channel()) + ); + + $_REQUEST['success'] = false; + + if ($r) { + $_REQUEST['success'] = true; + } + + + if (!intval($contact['abook_self'])) { + if ($new_friend) { + Master::Summon(['Notifier', 'permission_accept', $contact_id]); + } + + Master::Summon([ + 'Notifier', + (($new_friend) ? 'permission_create' : 'permission_update'), + $contact_id + ]); + } + + if ($new_friend) { + $default_group = $channel['channel_default_group']; + if ($default_group) { + $g = AccessList::by_hash(local_channel(), $default_group); + if ($g) { + AccessList::member_add(local_channel(), '', $contact['abook_xchan'], $g['id']); + } + } + + // Check if settings permit ("post new friend activity" is allowed, and + // friends in general or this friend in particular aren't hidden) + // and send out a new friend activity + + $pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0", + intval($channel['channel_id']) + ); + if (($pr) && (!intval($contact['abook_hidden'])) && (intval(get_pconfig($channel['channel_id'], 'system', 'post_newfriend')))) { + $xarr = []; + + $xarr['item_wall'] = 1; + $xarr['item_origin'] = 1; + $xarr['item_thread_top'] = 1; + $xarr['owner_xchan'] = $xarr['author_xchan'] = $channel['channel_hash']; + $xarr['allow_cid'] = $channel['channel_allow_cid']; + $xarr['allow_gid'] = $channel['channel_allow_gid']; + $xarr['deny_cid'] = $channel['channel_deny_cid']; + $xarr['deny_gid'] = $channel['channel_deny_gid']; + $xarr['item_private'] = (($xarr['allow_cid'] || $xarr['allow_gid'] || $xarr['deny_cid'] || $xarr['deny_gid']) ? 1 : 0); + + $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . $contact['xchan_url'] . ']' . $contact['xchan_name'] . '[/zrl]'; + + $xarr['body'] .= "\n\n\n" . '[zrl=' . $contact['xchan_url'] . '][zmg=80x80]' . $contact['xchan_photo_m'] . '[/zmg][/zrl]'; + + post_activity_item($xarr); + + } + + // pull in a bit of content if there is any to pull in + Master::Summon(['Onepoll', $contact_id]); + + } + + // Refresh the structure in memory with the new data + $this->init(); + + if ($new_friend) { + $arr = ['channel_id' => local_channel(), 'abook' => App::$poi]; + call_hooks('accept_follow', $arr); + } + + $this->contactedit_clone(); + $this->get(); + + killme(); + + return; + + } + + + /* @brief Generate content of contact edit page + * + * + */ + + function get() { + + if (!local_channel()) { + killme(); + } + + if (!App::$poi) { + killme(); + } + + + $channel = App::get_channel(); + $contact_id = App::$poi['abook_id']; + $contact = App::$poi; + $section = ((array_key_exists('section', $_REQUEST)) ? $_REQUEST['section'] : 'roles'); + $sub_section = ((array_key_exists('sub_section', $_REQUEST)) ? $_REQUEST['sub_section'] : ''); + + + if (argc() == 3) { + $cmd = argv(2); + $ret = $this->do_action($contact, $cmd); + $contact = App::$poi; + + $tools_html = replace_macros(get_markup_template("contact_edit_tools.tpl"), [ + '$tools_label' => t('Contact Tools'), + '$tools' => $this->get_tools($contact), + ]); + + $ret['tools'] = $tools_html; + + json_return_and_die($ret); + } + + $groups = []; + + if (Apps::system_app_installed(local_channel(), 'Privacy Groups')) { + + $r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", + intval(local_channel()) + ); + + $member_of = AccessList::containing(local_channel(), $contact['xchan_hash']); + + if ($r) { + foreach ($r as $rr) { + $default_group = false; + if ($rr['hash'] === $channel['channel_default_group']) { + $default_group = true; + } + + $groups[] = [ + 'pgrp_id_' . $rr['id'], + $rr['gname'], + // if it's a new contact preset the default group if we have one + (($default_group && $contact['abook_pending']) ? 1 : in_array($rr['id'], $member_of)), + '', + [t('No'), t('Yes')] + ]; + } + } + } + + $slide = ''; + + if (Apps::system_app_installed(local_channel(), 'Affinity Tool')) { + + $labels = [ + t('Me'), + t('Family'), + t('Friends'), + t('Acquaintances'), + t('All') + ]; + call_hooks('affinity_labels', $labels); + $label_str = ''; + + if ($labels) { + foreach ($labels as $l) { + if ($label_str) { + $label_str .= ", '|'"; + $label_str .= ", '" . $l . "'"; + } + else + $label_str .= "'" . $l . "'"; + } + } + + $slider_tpl = get_markup_template('contact_slider.tpl'); + + $slideval = intval($contact['abook_closeness']); + + $slide = replace_macros($slider_tpl, [ + '$min' => 1, + '$val' => $slideval, + '$labels' => $label_str, + ]); + } + + $perms = []; + $global_perms = Permissions::Perms(); + $existing = get_all_perms(local_channel(), $contact['abook_xchan'], false); + $unapproved = ['pending', t('Approve this contact'), '', t('Accept contact to allow communication'), [t('No'), ('Yes')]]; + $multiprofs = ((feature_enabled(local_channel(), 'multi_profiles')) ? true : false); + + $theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'", + intval(local_channel()), + dbesc($contact['abook_xchan']) + ); + + $their_perms = []; + if ($theirs) { + foreach ($theirs as $t) { + $their_perms[$t['k']] = $t['v']; + } + } + + foreach ($global_perms as $k => $v) { + $thisperm = $existing[$k]; + $checkinherited = PermissionLimits::Get(local_channel(), $k); + $perms[] = ['perms_' . $k, $v, ((array_key_exists($k, $their_perms)) ? intval($their_perms[$k]) : ''), $thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '0' : '1'), '', $checkinherited]; + } + + $pcat = new Permcat(local_channel()); + $pcatlist = $pcat->listing(); + $default_role = get_pconfig(local_channel(), 'system', 'default_permcat'); + $current_permcat = (($contact['abook_pending']) ? $default_role : $contact['abook_role']); + + $roles_dict = []; + foreach ($pcatlist as $role) { + $roles_dict[$role['name']] = $role['localname']; + } + + + if (!$current_permcat) { + notice(t('Please select a role for this contact!') . EOL); + $permcats[] = ''; + } + + if ($pcatlist) { + foreach ($pcatlist as $pc) { + $permcats[$pc['name']] = $pc['localname']; + } + } + + $locstr = locations_by_netid($contact['xchan_hash']); + if (!$locstr) { + $locstr = unpunify($contact['xchan_url']); + } + + $clone_warn = ''; + $clonable = in_array($contact['xchan_network'], ['zot6', 'rss']); + if (!$clonable) { + $clone_warn = ''; + $clone_warn .= ((intval($contact['abook_not_here'])) + ? t('This contact is unreachable from this location.') + : t('This contact may be unreachable from other channel locations.') + ); + $clone_warn .= '
' . t('Location independence is not supported by their network.'); + } + + $header_card = '  ' . $contact['xchan_name']; + + $header_html = replace_macros(get_markup_template("contact_edit_header.tpl"), [ + '$img_src' => $contact['xchan_photo_s'], + '$name' => $contact['xchan_name'], + '$addr' => (($contact['xchan_addr']) ? $contact['xchan_addr'] : $contact['xchan_url']), + '$href' => ((is_matrix_url($contact['xchan_url'])) ? zid($contact['xchan_url']) : $contact['xchan_url']), + '$link_label' => t('View profile'), + '$is_group' => $contact['xchan_pubforum'], + '$group_label' => t('This is a group/forum channel') + ]); + + $tools_html = replace_macros(get_markup_template("contact_edit_tools.tpl"), [ + '$tools_label' => t('Contact Tools'), + '$tools' => $this->get_tools($contact), + ]); + + $tpl = get_markup_template("contact_edit.tpl"); + + $o = replace_macros($tpl, [ + '$permcat' => ['permcat', t('Select a role for this contact'), $current_permcat, '', $permcats], + '$permcat_new' => t('Contact roles'), + '$permcat_value' => bin2hex($current_permcat), +// '$addr' => unpunify($contact['xchan_addr']), +// '$primeurl' => unpunify($contact['xchan_url']), + '$section' => $section, + '$sub_section' => $sub_section, + '$groups' => $groups, +// '$addr_text' => t('This contacts\'s primary address is'), +// '$loc_text' => t('Available locations:'), +// '$locstr' => $locstr, +// '$unclonable' => $clone_warn, + '$lbl_slider' => t('Slide to adjust your degree of friendship'), + '$connfilter' => feature_enabled(local_channel(), 'connfilter'), + '$connfilter_label' => t('Custom Filter'), + '$incl' => ['abook_incl', t('Only import posts with this text'), $contact['abook_incl'], t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')], + '$excl' => ['abook_excl', t('Do not import posts with this text'), $contact['abook_excl'], t('words one per line or #tags or /patterns/ or lang=xx, leave blank to import all posts')], + '$slide' => $slide, +// '$pending_label' => t('Contact Pending Approval'), +// '$is_pending' => (intval($contact['abook_pending']) ? 1 : ''), +// '$unapproved' => $unapproved, + '$submit' => ((intval($contact['abook_pending'])) ? t('Approve contact') : t('Submit')), + '$close' => (($contact['abook_closeness']) ? $contact['abook_closeness'] : 80), + '$them' => t('Their'), + '$me' => t('My'), + '$perms' => $perms, +// '$lastupdtext' => t('Last update:'), +// '$last_update' => relative_date($contact['abook_connected']), + '$profile_select' => contact_profile_assign($contact['abook_profile']), + '$multiprofs' => $multiprofs, + '$contact_id' => $contact['abook_id'], +// '$name' => $contact['xchan_name'], + ]); + + $arr = ['contact' => $contact, 'output' => $o]; + + call_hooks('contact_edit', $arr); + + if (is_ajax()) { + json_return_and_die([ + 'success' => ((intval($_REQUEST['success'])) ? intval($_REQUEST['success']) : 1), + 'message' => (($_REQUEST['success']) ? t('Contact updated') : t('Contact update failed')), + 'id' => $contact_id, + 'title' => $header_html, + 'role' => ((intval($contact['abook_pending'])) ? '' : $roles_dict[$current_permcat]), + 'body' => $arr['output'], + 'tools' => $tools_html, + 'submit' => ((intval($contact['abook_pending'])) ? t('Approve connection') : t('Submit')), + 'pending' => intval($contact['abook_pending']) + ]); + } + + return $arr['output']; + + } + + function contactedit_clone() { + + if (!App::$poi) + return; + + $channel = App::get_channel(); + + $clone = App::$poi; + + unset($clone['abook_id']); + unset($clone['abook_account']); + unset($clone['abook_channel']); + + $abconfig = load_abconfig($channel['channel_id'], $clone['abook_xchan']); + if ($abconfig) + $clone['abconfig'] = $abconfig; + + Libsync::build_sync_packet(0 /* use the current local_channel */, ['abook' => [$clone]]); + } + + function do_action($contact, $cmd) { + $ret = [ + 'sucess' => false, + 'message' => '' + ]; + + if ($cmd === 'resetphoto') { + q("update xchan set xchan_photo_date = '2001-01-01 00:00:00' where xchan_hash = '%s'", + dbesc($contact['xchan_hash']) + ); + $cmd = 'refresh'; + } + + if ($cmd === 'refresh') { + if ($contact['xchan_network'] === 'zot6') { + if (Libzot::refresh($contact, App::get_channel())) { + $ret['success'] = true; + $ret['message'] = t('Refresh succeeded'); + } + else { + $ret['message'] = t('Refresh failed - channel is currently unavailable'); + } + } + else { + // if you are on a different network we'll force a refresh of the connection basic info + Master::Summon(['Notifier', 'permission_update', $contact['abook_id']]); + $ret['success'] = true; + $ret['message'] = t('Refresh succeeded'); + } + + return $ret; + } + + if ($cmd === 'block') { + if (abook_toggle_flag($contact, ABOOK_FLAG_BLOCKED)) { + $this->init(); // refresh data + + $this->contactedit_clone(); + $ret['success'] = true; + $ret['message'] = t('Block status updated'); + } + else { + $ret['success'] = false; + $ret['message'] = t('Block failed'); + } + return $ret; + } + + if ($cmd === 'ignore') { + if (abook_toggle_flag($contact, ABOOK_FLAG_IGNORED)) { + $this->init(); // refresh data + + $this->contactedit_clone(); + $ret['success'] = true; + $ret['message'] = t('Ignore status updated'); + } + else { + $ret['success'] = false; + $ret['message'] = t('Ignore failed'); + } + return $ret; + } + + if ($cmd === 'archive') { + if (abook_toggle_flag($contact, ABOOK_FLAG_ARCHIVED)) { + $this->init(); // refresh data + + $this->contactedit_clone(); + $ret['success'] = true; + $ret['message'] = t('Archive status updated'); + } + else { + $ret['success'] = false; + $ret['message'] = t('Archive failed'); + } + return $ret; + } + + if ($cmd === 'hide') { + if (abook_toggle_flag($contact, ABOOK_FLAG_HIDDEN)) { + $this->init(); // refresh data + + $this->contactedit_clone(); + $ret['success'] = true; + $ret['message'] = t('Hide status updated'); + } + else { + $ret['success'] = false; + $ret['message'] = t('Hide failed'); + } + return $ret; + } + + // We'll prevent somebody from unapproving an already approved contact. + // Though maybe somebody will want this eventually (??) + + //if ($cmd === 'approve') { + //if (intval($contact['abook_pending'])) { + //if (abook_toggle_flag($contact, ABOOK_FLAG_PENDING)) { + //$this->contactedit_clone(); + //} + //else + //notice(t('Unable to set address book parameters.') . EOL); + //} + //goaway(z_root() . '/connedit/' . $contact_id); + //} + + + if ($cmd === 'drop') { + + if (contact_remove(local_channel(), $contact['abook_id'])) { + + Master::Summon(['Notifier', 'purge', local_channel(), $contact['xchan_hash']]); + Libsync::build_sync_packet(0 /* use the current local_channel */, + ['abook' => [ + [ + 'abook_xchan' => $contact['abook_xchan'], + 'entry_deleted' => true + ] + ] + ]); + + $ret['success'] = true; + $ret['message'] = t('Contact removed'); + } + else { + $ret['success'] = false; + $ret['message'] = t('Delete failed'); + } + return $ret; + } + } + + function get_tools($contact) { + return [ + + 'refresh' => [ + 'label' => t('Refresh Permissions'), + 'title' => t('Fetch updated permissions'), + ], + + 'rephoto' => [ + 'label' => t('Refresh Photo'), + 'title' => t('Fetch updated photo'), + ], + + + 'block' => [ + 'label' => (intval($contact['abook_blocked']) ? t('Unblock') : t('Block')), + 'sel' => (intval($contact['abook_blocked']) ? 'active' : ''), + 'title' => t('Block (or Unblock) all communications with this connection'), + 'info' => (intval($contact['abook_blocked']) ? t('This connection is blocked!') : ''), + ], + + 'ignore' => [ + 'label' => (intval($contact['abook_ignored']) ? t('Unignore') : t('Ignore')), + 'sel' => (intval($contact['abook_ignored']) ? 'active' : ''), + 'title' => t('Ignore (or Unignore) all inbound communications from this connection'), + 'info' => (intval($contact['abook_ignored']) ? t('This connection is ignored!') : ''), + ], + + 'archive' => [ + 'label' => (intval($contact['abook_archived']) ? t('Unarchive') : t('Archive')), + 'sel' => (intval($contact['abook_archived']) ? 'active' : ''), + 'title' => t('Archive (or Unarchive) this connection - mark channel dead but keep content'), + 'info' => (intval($contact['abook_archived']) ? t('This connection is archived!') : ''), + ], + + 'hide' => [ + 'label' => (intval($contact['abook_hidden']) ? t('Unhide') : t('Hide')), + 'sel' => (intval($contact['abook_hidden']) ? 'active' : ''), + 'title' => t('Hide or Unhide this connection from your other connections'), + 'info' => (intval($contact['abook_hidden']) ? t('This connection is hidden!') : ''), + ], + + 'delete' => [ + 'label' => t('Delete'), + 'sel' => '', + 'title' => t('Delete this connection'), + ], + + ]; + } + +} diff --git a/Zotlabs/Module/Contactgroup.php b/Zotlabs/Module/Contactgroup.php index 36aaf7da0..3e88179fb 100644 --- a/Zotlabs/Module/Contactgroup.php +++ b/Zotlabs/Module/Contactgroup.php @@ -1,17 +1,17 @@ 2) && (intval(argv(1))) && (argv(2))) { $r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc(base64url_decode(argv(2))), @@ -20,9 +20,9 @@ class Contactgroup extends \Zotlabs\Web\Controller { if($r) $change = $r[0]['abook_xchan']; } - + if((argc() > 1) && (intval(argv(1)))) { - + $r = q("SELECT * FROM pgrp WHERE id = %d AND uid = %d AND deleted = 0 LIMIT 1", intval(argv(1)), intval(local_channel()) @@ -30,25 +30,25 @@ class Contactgroup extends \Zotlabs\Web\Controller { if(! $r) { killme(); } - + $group = $r[0]; - $members = group_get_members($group['id']); + $members = AccessList::members(local_channel(), $group['id']); $preselected = array(); if(count($members)) { foreach($members as $member) $preselected[] = $member['xchan_hash']; } - + if($change) { if(in_array($change,$preselected)) { - group_rmv_member(local_channel(),$group['gname'],$change); + AccessList::member_remove(local_channel(),$group['gname'],$change); } else { - group_add_member(local_channel(),$group['gname'],$change); + AccessList::member_add(local_channel(),$group['gname'],$change); } } } - + killme(); } } diff --git a/Zotlabs/Module/Defperms.php b/Zotlabs/Module/Defperms.php index 309a5a65a..70270d36b 100644 --- a/Zotlabs/Module/Defperms.php +++ b/Zotlabs/Module/Defperms.php @@ -8,7 +8,6 @@ use Zotlabs\Lib\Libsync; require_once('include/socgraph.php'); require_once('include/selectors.php'); -require_once('include/group.php'); require_once('include/photos.php'); class Defperms extends Controller { @@ -23,8 +22,8 @@ class Defperms extends Controller { if(! local_channel()) return; - if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) - return; + //if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) + // return; $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash @@ -50,8 +49,8 @@ class Defperms extends Controller { if(! local_channel()) return; - if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) - return; + //if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) + // return; $contact_id = intval(argv(1)); if(! $contact_id) @@ -183,12 +182,12 @@ class Defperms extends Controller { return login(); } - if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) { - //Do not display any associated widgets at this point - App::$pdl = ''; - $papp = Apps::get_papp('Default Permissions'); - return Apps::app_render($papp, 'module'); - } + //~ if(! Apps::system_app_installed(local_channel(), 'Default Permissions')) { + //~ //Do not display any associated widgets at this point + //~ App::$pdl = ''; + //~ $papp = Apps::get_papp('Default Permissions'); + //~ return Apps::app_render($papp, 'module'); + //~ } $section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : ''); $channel = App::get_channel(); diff --git a/Zotlabs/Module/Follow.php b/Zotlabs/Module/Follow.php index 4fe20f56b..94daa4c70 100644 --- a/Zotlabs/Module/Follow.php +++ b/Zotlabs/Module/Follow.php @@ -108,7 +108,7 @@ class Follow extends Controller { } Libsync::build_sync_packet(0, [ 'abook' => [ $clone ] ], true); - $can_view_stream = their_perms_contains($channel['channel_id'],$clone['abook_xchan'],'view_stream'); + $can_view_stream = intval(get_abconfig($channel['channel_id'], $clone['abook_xchan'], 'their_perms', 'view_stream')); // If we can view their stream, pull in some posts @@ -117,7 +117,7 @@ class Follow extends Controller { } if ($interactive) { - goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?follow=1'); + goaway(z_root() . '/connections#' . $result['abook']['abook_id']); } else { json_return_and_die([ 'success' => true ]); diff --git a/Zotlabs/Module/Group.php b/Zotlabs/Module/Group.php index a2d55a325..4c6b0c838 100644 --- a/Zotlabs/Module/Group.php +++ b/Zotlabs/Module/Group.php @@ -5,8 +5,7 @@ use App; use Zotlabs\Web\Controller; use Zotlabs\Lib\Apps; use Zotlabs\Lib\Libsync; - -require_once('include/group.php'); +use Zotlabs\Lib\AccessList; class Group extends Controller { @@ -41,16 +40,17 @@ class Group extends Controller { $name = notags(trim($_POST['groupname'])); $public = intval($_POST['public']); - $r = group_add(local_channel(),$name,$public); + $r = AccessList::add(local_channel(),$name,$public); + $group_hash = $r; + if($r) { info( t('Privacy group created.') . EOL ); } else { notice( t('Could not create privacy group.') . EOL ); } - goaway(z_root() . '/group'); - } + if((argc() == 2) && (intval(argv(1)))) { check_form_security_token_redirectOnErr('/group', 'group_edit'); @@ -65,10 +65,11 @@ class Group extends Controller { } $group = $r[0]; $groupname = notags(trim($_POST['groupname'])); + $group_hash = $group['hash']; $public = intval($_POST['public']); $hookinfo = [ 'pgrp_extras' => '', 'group'=>$group['id'] ]; - call_hooks ('privacygroup_extras_post',$hookinfo); + call_hooks('privacygroup_extras_post',$hookinfo); if((strlen($groupname)) && (($groupname != $group['gname']) || ($public != $group['visible']))) { $r = q("UPDATE pgrp SET gname = '%s', visible = %d WHERE uid = %d AND id = %d", @@ -79,13 +80,25 @@ class Group extends Controller { ); if($r) info( t('Privacy group updated.') . EOL ); + } + } + $channel = App::get_channel(); - Libsync::build_sync_packet(local_channel(),null,true); - } + $default_group = ((isset($_POST['set_default_group'])) ? $group_hash : (($channel['channel_default_group'] === $group_hash) ? '' : $channel['channel_default_group'])); + $default_acl = ((isset($_POST['set_default_acl'])) ? '<' . $group_hash . '>' : (($channel['channel_allow_gid'] === '<' . $group_hash . '>') ? '' : $channel['channel_allow_gid'])); + + q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' + where channel_id = %d", + dbesc($default_group), + dbesc($default_acl), + intval(local_channel()) + ); + + Libsync::build_sync_packet(local_channel(),null,true); + + goaway(z_root() . '/group/' . argv(1) . ((argv(2)) ? '/' . argv(2) : '')); - goaway(z_root() . '/group/' . argv(1) . '/' . argv(2)); - } return; } @@ -127,7 +140,7 @@ class Group extends Controller { foreach($groups as $group) { $entries[$i]['name'] = $group['gname']; $entries[$i]['id'] = $group['id']; - $entries[$i]['count'] = count(group_get_members($group['id'])); + $entries[$i]['count'] = count(AccessList::members(local_channel(), $group['id'])); $i++; } @@ -135,6 +148,10 @@ class Group extends Controller { call_hooks ('privacygroup_extras',$hookinfo); $pgrp_extras = $hookinfo['pgrp_extras']; + $is_default_acl = ['set_default_acl', t('Post to this group by default'), 0, '', [t('No'), t('Yes')]]; + $is_default_group = ['set_default_group', t('Add new contacts to this group by default'), 0, '', [t('No'), t('Yes')]]; + + $tpl = get_markup_template('privacy_groups.tpl'); $o = replace_macros($tpl, [ '$title' => t('Privacy Groups'), @@ -143,16 +160,19 @@ class Group extends Controller { // new group form '$gname' => array('groupname',t('Privacy group name')), - '$public' => array('public',t('Members are visible to other channels'), false), + '$public' => array('public',t('Members are visible to other channels'), 0, '', [t('No'), t('Yes')]), '$pgrp_extras' => $pgrp_extras, '$form_security_token' => get_form_security_token("group_edit"), '$submit' => t('Submit'), + '$is_default_acl' => $is_default_acl, + '$is_default_group' => $is_default_group, // groups list '$title' => t('Privacy Groups'), '$name_label' => t('Name'), '$count_label' => t('Members'), '$entries' => $entries + ]); return $o; @@ -174,7 +194,7 @@ class Group extends Controller { intval(local_channel()) ); if($r) - $result = group_rmv(local_channel(),$r[0]['gname']); + $result = AccessList::remove(local_channel(),$r[0]['gname']); if($result) { $hookinfo = [ 'pgrp_extras' => '', 'group' => argv(2) ]; call_hooks ('privacygroup_extras_drop',$hookinfo); @@ -215,7 +235,7 @@ class Group extends Controller { $group = $r[0]; - $members = group_get_members($group['id']); + $members = AccessList::members(local_channel(), $group['id']); $preselected = array(); if(count($members)) { @@ -227,13 +247,13 @@ class Group extends Controller { if($change) { if(in_array($change,$preselected)) { - group_rmv_member(local_channel(),$group['gname'],$change); + AccessList::member_remove(local_channel(),$group['gname'],$change); } else { - group_add_member(local_channel(),$group['gname'],$change); + AccessList::member_add(local_channel(),$group['gname'],$change); } - $members = group_get_members($group['id']); + $members = AccessList::members(local_channel(), $group['id']); $preselected = array(); if(count($members)) { @@ -252,7 +272,7 @@ class Group extends Controller { '$gname' => array('groupname',t('Privacy group name: '),$group['gname'], ''), '$gid' => $group['id'], '$drop' => $drop_txt, - '$public' => array('public',t('Members are visible to other channels'), $group['visible'], ''), + '$public' => array('public',t('Members are visible to other channels'), $group['visible'], '', [t('No'), t('Yes')]), '$form_security_token_edit' => get_form_security_token('group_edit'), '$delete' => t('Delete Group'), '$form_security_token_drop' => get_form_security_token("group_drop"), @@ -280,7 +300,7 @@ class Group extends Controller { $groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode); } else - group_rmv_member(local_channel(),$group['gname'],$member['xchan_hash']); + AccessList::member_remove(local_channel(),$group['gname'],$member['xchan_hash']); } $r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash WHERE abook_channel = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc", @@ -302,6 +322,15 @@ class Group extends Controller { $context['$desc'] = t('Click a channel to toggle membership'); $context['$pgrp_extras'] = $pgrp_extras; + $channel = App::get_channel(); + +//hz_syslog(print_r($group,true)); +//hz_syslog(print_r($channel,true)); + + $context['$is_default_acl'] = ['set_default_acl', t('Post to this group by default'), intval($group['hash'] === trim($channel['channel_allow_gid'], '<>')), '', [t('No'), t('Yes')]]; + $context['$is_default_group'] = ['set_default_group', t('Add new contacts to this group by default'), intval($group['hash'] === $channel['channel_default_group']), '', [t('No'), t('Yes')]]; + + if($change) { $tpl = get_markup_template('groupeditor.tpl'); echo replace_macros($tpl, $context); diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 9b76c7569..66629fa2b 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -416,6 +416,7 @@ class Item extends Controller { $expires = NULL_DATE; + $comments_closed = NULL_DATE; $route = ''; $parent_item = null; @@ -692,6 +693,7 @@ class Item extends Controller { $postopts = $orig_post['postopts']; $created = $orig_post['created']; $expires = $orig_post['expires']; + $comments_closed = $orig_post['comments_closed']; $mid = $orig_post['mid']; $parent_mid = $orig_post['parent_mid']; $plink = $orig_post['plink']; @@ -794,13 +796,7 @@ class Item extends Controller { // if this is a wall-to-wall post to a group, turn it into a direct message - $role = get_pconfig($profile_uid, 'system', 'permissions_role'); - - $rolesettings = PermissionRoles::role_perms($role); - - $channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal'; - - $is_group = (($channel_type === 'group') ? true : false); + $is_group = get_pconfig($profile_uid, 'system', 'group_actor'); if (($is_group) && ($walltowall) && (!$walltowall_comment)) { $groupww = true; @@ -994,8 +990,9 @@ class Item extends Controller { $notify_type = (($parent) ? 'comment-new' : 'wall-new'); + $uuid = (($message_id) ? $message_id : item_message_id()); + if (!$mid) { - $uuid = (($message_id) ? $message_id : item_message_id()); $mid = z_root() . '/item/' . $uuid; } @@ -1015,10 +1012,22 @@ class Item extends Controller { } if ($obj) { - $obj['url'] = $mid; - $obj['attributedTo'] = channel_url($channel); - $datarray['obj'] = $obj; - $obj_type = 'Question'; + $obj['url'] = $mid; + $obj['id'] = $mid; + $obj['diaspora:guid'] = $uuid; + $obj['attributedTo'] = channel_url($channel); + $obj['published'] = $created; + + $datarray['obj'] = $obj; + + if ($obj['endTime']) { + $d = datetime_convert('UTC','UTC', $obj['endTime']); + if ($d > NULL_DATE) { + $comments_closed = $d; + } + } + + $obj_type = 'Question'; } if (!$parent_mid) { @@ -1082,6 +1091,7 @@ class Item extends Controller { $datarray['created'] = $created; $datarray['edited'] = (($orig_post) ? datetime_convert() : $created); $datarray['expires'] = $expires; + $datarray['comments_closed'] = $comments_closed; $datarray['commented'] = (($orig_post) ? datetime_convert() : $created); $datarray['received'] = (($orig_post) ? datetime_convert() : $created); $datarray['changed'] = (($orig_post) ? datetime_convert() : $created); @@ -1594,6 +1604,8 @@ class Item extends Controller { $obj['endTime'] = datetime_convert(date_default_timezone_get(), 'UTC', 'now + ' . $expire_value . ' ' . $expire_unit, ATOM_TIME); + $obj['directMessage'] = (intval($item['item_private']) === 2); + if ($item['item_private']) { $obj['to'] = Activity::map_acl($item); } diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 03c56b9a2..016a0a309 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -1,12 +1,11 @@ %') . "' ) and id = parent $item_normal ) "; - $x = group_rec_byhash(local_channel(), $group_hash); + $x = AccessList::by_hash(local_channel(), $group_hash); if($x) { $title = replace_macros(get_markup_template('section_title.tpl'), array( diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php index 3b0b35258..5989e3da6 100644 --- a/Zotlabs/Module/New_channel.php +++ b/Zotlabs/Module/New_channel.php @@ -170,12 +170,12 @@ class New_channel extends \Zotlabs\Web\Controller { $privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "" ); - $perm_roles = \Zotlabs\Access\PermissionRoles::roles(); + $perm_roles = \Zotlabs\Access\PermissionRoles::channel_roles(); $name = array('name', t('Channel name'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), $name_help, "*"); $nickhub = '@' . \App::get_hostname(); $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), $nick_help, "*"); - $role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel permission role compatible with your usage needs and privacy requirements.') . '
' . '' . t('Read more about channel permission roles') . '',$perm_roles); + $role = array('permissions_role' , t('Channel role'), ($privacy_role) ? $privacy_role : 'personal', '', $perm_roles); $o = replace_macros(get_markup_template('new_channel.tpl'), array( '$title' => t('Create a Channel'), diff --git a/Zotlabs/Module/Permcats.php b/Zotlabs/Module/Permcats.php index 58566373a..a46253ec2 100644 --- a/Zotlabs/Module/Permcats.php +++ b/Zotlabs/Module/Permcats.php @@ -6,6 +6,7 @@ use App; use Zotlabs\Web\Controller; use Zotlabs\Lib\Apps; use Zotlabs\Lib\Libsync; +use Zotlabs\Lib\AccessList; class Permcats extends Controller { @@ -14,24 +15,59 @@ class Permcats extends Controller { if(! local_channel()) return; - if(! Apps::system_app_installed(local_channel(), 'Permission Categories')) - return; - $channel = App::get_channel(); check_form_security_token_redirectOnErr('/permcats', 'permcats'); - $all_perms = \Zotlabs\Access\Permissions::Perms(); - $name = escape_tags(trim($_POST['name'])); - if(! $name) { + $is_system_role = isset($_POST['is_system_role']); + $return_path = z_root() . '/permcats/' . $_POST['return_path']; + $group_hash = ((isset($_POST['group_select'])) ? $_POST['group_select'] : ''); + $contacts = []; + + if ($group_hash === 'all_contacts') { + $r = q("SELECT abook_xchan FROM abook WHERE abook_channel = %d and abook_self = 0 and abook_pending = 0", + intval(local_channel()) + ); + + if ($r) { + $contacts = ids_to_array($r, 'abook_xchan'); + } + } + + if (!$contacts && $group_hash) { + $group = AccessList::by_hash(local_channel(), $group_hash); + } + + if ($group) { + $contacts = AccessList::members_xchan(local_channel(), $group['id']); + } + + if(! $name ) { notice( t('Permission category name is required.') . EOL); return; } + set_pconfig(local_channel(), 'system', 'default_permcat', 'default'); + + if (isset($_POST['default_role'])) { + set_pconfig(local_channel(), 'system', 'default_permcat', $name); + } + + if ($is_system_role) { + // if we have a system role just set the default and assign if aplicable and be done with it + if ($contacts) + \Zotlabs\Lib\Permcat::assign($channel, $name, $contacts); + + info( t('Contact role saved.') . EOL); + Libsync::build_sync_packet(); + goaway($return_path); + return; + } $pcarr = []; + $all_perms = \Zotlabs\Access\Permissions::Perms(); if($all_perms) { foreach($all_perms as $perm => $desc) { @@ -41,11 +77,16 @@ class Permcats extends Controller { } } - \Zotlabs\Lib\Permcat::update(local_channel(),$name,$pcarr); + \Zotlabs\Lib\Permcat::update(local_channel(), $name, $pcarr); + + if ($contacts) { + \Zotlabs\Lib\Permcat::assign($channel, $name, $contacts); + } Libsync::build_sync_packet(); - info( t('Permission category saved.') . EOL); + info( t('Contact role saved.') . EOL); + goaway($return_path); return; } @@ -56,13 +97,6 @@ class Permcats extends Controller { if(! local_channel()) return; - if(! Apps::system_app_installed(local_channel(), 'Permission Categories')) { - //Do not display any associated widgets at this point - App::$pdl = ''; - $papp = Apps::get_papp('Permission Categories'); - return Apps::app_render($papp, 'module'); - } - $channel = App::get_channel(); if(argc() > 1) @@ -70,24 +104,49 @@ class Permcats extends Controller { if(argc() > 2 && argv(2) === 'drop') { \Zotlabs\Lib\Permcat::delete(local_channel(),$name); + + // TODO: assign all members of the deleted role to the default role + Libsync::build_sync_packet(); json_return_and_die([ 'success' => true ]); } - $desc = t('Use this form to create permission rules for various classes of people or connections.'); - $existing = []; $pcat = new \Zotlabs\Lib\Permcat(local_channel()); $pcatlist = $pcat->listing(); + +/* not yet ready + $test = $pcatlist[4]['perms']; + $role_sql = ''; + + foreach ($test as $t) + $role_sql .= "( k = '" . dbesc($t['name']) . "' AND v = '" . intval($t['value']) . "' ) OR "; + + $role_sql = rtrim($role_sql, ' OR '); + + // get all xchans belonging to a permission role + $q = q("SELECT xchan FROM abconfig WHERE chan = %d AND cat = 'my_perms' AND ( $role_sql ) GROUP BY xchan HAVING count(xchan) = %d", + intval(local_channel()), + intval(count($test)) + ); +*/ + + $is_system_role = false; $permcats = []; if($pcatlist) { foreach($pcatlist as $pc) { - if(($pc['name']) && ($name) && ($pc['name'] == $name)) + if(($pc['name']) && ($name) && ($pc['name'] == $name)) { $existing = $pc['perms']; - if(! $pc['system']) - $permcats[bin2hex($pc['name'])] = $pc['localname']; + if (isset($pc['system']) && intval($pc['system'])) + $is_system_role = $pc['name']; + } + + $permcats[bin2hex($pc['name'])] = $pc['localname']; + + if($pc['name'] == $name) + $localname = $pc['localname']; } } @@ -98,33 +157,56 @@ class Permcats extends Controller { $checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k); if($existing[$k]) - $thisperm = "1"; - - $perms[] = array('perms_' . $k, $v, '',$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited); + $thisperm = 1; + + $perms[] = [ + 'perms_' . $k, + $v, + '', + $thisperm, + 1, + (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), + '', + $checkinherited + ]; } + $is_default_role = (get_pconfig(local_channel(),'system','default_permcat','default') == $name); + + $group_select_options = [ + 'selected' => '', + 'form_id' => 'group_select', + 'label' => t('Assign this role to'), + 'after' => [ + 'name' => t('All my contacts'), + 'id' => 'all_contacts', + 'selected' => false + ] + ]; + $group_select = AccessList::select(local_channel(), $group_select_options); $tpl = get_markup_template("permcats.tpl"); $o .= replace_macros($tpl, array( '$form_security_token' => get_form_security_token("permcats"), - '$title' => t('Permission Categories'), - '$desc' => $desc, - '$desc2' => $desc2, + '$default_role' => array('default_role', t('Use this role as default for new contacts'), intval($is_default_role), '', [t('No'), t('Yes')]), + + '$title' => t('Contact Roles'), '$tokens' => $t, '$permcats' => $permcats, '$atoken' => $atoken, '$url1' => z_root() . '/channel/' . $channel['channel_address'], '$url2' => z_root() . '/photos/' . $channel['channel_address'], - '$name' => array('name', t('Permission category name') . ' *', (($name) ? $name : ''), ''), - '$me' => t('My Settings'), + '$name' => ['name', t('Role name') . ' *', (($localname) ? $localname : ''), (($is_system_role) ? t('System role - not editable') : '') , '', (($is_system_role) ? 'disabled' : '')], '$perms' => $perms, '$inherited' => t('inherited'), - '$notself' => 0, - '$self' => 1, - '$permlbl' => t('Individual Permissions'), - '$permnote' => t('Some permissions may be inherited from your channel\'s privacy settings, which have higher priority than individual settings. You can not change those settings here.'), - '$submit' => t('Submit') + '$is_system_role' => $is_system_role, + '$permlbl' => t('Role Permissions'), + '$permnote' => t('Some permissions may be inherited from your channel role, which have higher priority than contact role settings.'), + '$submit' => t('Submit'), + '$return_path' => argv(1), + '$group_select' => $group_select, + )); return $o; } diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php index 1512148b1..ca0ca4f1a 100644 --- a/Zotlabs/Module/Profiles.php +++ b/Zotlabs/Module/Profiles.php @@ -316,8 +316,6 @@ class Profiles extends \Zotlabs\Web\Controller { $work = fix_mce_lf(escape_tags(trim($_POST['work']))); $education = fix_mce_lf(escape_tags(trim($_POST['education']))); - $hide_friends = ((intval($_POST['hide_friends'])) ? 1: 0); - // start fresh and create a new vcard. TODO: preserve the original guid or whatever else needs saving // $orig_vcard = (($orig[0]['profile_vcard']) ? \Sabre\VObject\Reader::read($orig[0]['profile_vcard']) : null); @@ -513,6 +511,16 @@ class Profiles extends \Zotlabs\Web\Controller { $value = $locality . $comma1 . $region . $comma2 . $country_name; } + $hide_friends = ((intval($_POST['hide_friends'])) ? 1: 0); + + $suggestme = ((x($_POST, 'suggestme')) ? intval($_POST['suggestme']) : 0); + set_pconfig(local_channel(), 'system', 'suggestme', $suggestme); + + $show_presence = (((x($_POST, 'show_presence')) && (intval($_POST['show_presence']) == 1)) ? 1 : 0); + set_pconfig(local_channel(), 'system', 'show_online_status', $show_presence); + + $publish = ((x($_POST, 'profile_in_directory') && (intval($_POST['profile_in_directory']) == 1)) ? 1 : 0); + profile_activity($changes,$value); } @@ -551,7 +559,8 @@ class Profiles extends \Zotlabs\Web\Controller { employment = '%s', education = '%s', hide_friends = %d, - profile_vcard = '%s' + profile_vcard = '%s', + publish = %d WHERE id = %d AND uid = %d", dbesc($profile_name), dbesc($name), @@ -587,6 +596,7 @@ class Profiles extends \Zotlabs\Web\Controller { dbesc($education), intval($hide_friends), dbesc($profile_vcard), + intval($publish), intval(argv(1)), intval(local_channel()) ); @@ -675,13 +685,43 @@ class Profiles extends \Zotlabs\Web\Controller { else $fields = $profile_fields_basic; - $hide_friends = array( - 'hide_friends', - t('Hide your connections list from viewers of this profile'), - $r[0]['hide_friends'], - '', - array(t('No'),t('Yes')) - ); + $show_presence = []; + $profile_in_dir = ''; + $suggestme = ''; + $hide_friends = []; + $is_default = (($r[0]['is_default']) ? 1 : 0); + + if ($is_default) { + + $hide_friends = array( + 'hide_friends', + t('Hide my connections from viewers of this profile'), + $r[0]['hide_friends'], + '', + [t('No'), t('Yes')] + ); + + + $opt_tpl = get_markup_template("field_checkbox.tpl"); + if (get_config('system', 'publish_all')) { + $profile_in_dir = ''; + } + else { + $profile_in_dir = replace_macros($opt_tpl, [ + '$field' => ['profile_in_directory', t('Publish my default profile in the network directory'), $r[0]['publish'], '', [t('No'), t('Yes')]], + ]); + } + + $suggestme = get_pconfig(local_channel(), 'system', 'suggestme'); + $suggestme = (($suggestme === false) ? '0' : $suggestme); // default if not set: 0 + + $suggestme = replace_macros($opt_tpl, [ + '$field' => ['suggestme', t('Suggest me as a potential contact to new members'), $suggestme, '', [t('No'), t('Yes')]], + ]); + + $show_presence_val = intval(get_pconfig(local_channel(), 'system', 'show_online_status')); + $show_presence = ['show_presence', t('Reveal my online status'), $show_presence_val, '', [t('No'), t('Yes')]]; + } $q = q("select * from profdef where true"); if($q) { @@ -710,7 +750,7 @@ class Profiles extends \Zotlabs\Web\Controller { if(! $f) $f = 'ymd'; - $is_default = (($r[0]['is_default']) ? 1 : 0); + $tpl = get_markup_template("profile_edit.tpl"); $o .= replace_macros($tpl,array( @@ -724,7 +764,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$banner' => t('Edit Profile Details'), '$submit' => t('Submit'), '$viewprof' => t('View this profile'), - '$editvis' => t('Edit visibility'), + '$editvis' => t('Edit visibility'), '$tools_label' => t('Profile Tools'), '$coverpic' => t('Change cover photo'), '$profpic' => t('Change profile photo'), @@ -732,7 +772,7 @@ class Profiles extends \Zotlabs\Web\Controller { '$cl_prof' => t('Clone this profile'), '$del_prof' => t('Delete this profile'), '$addthing' => t('Add profile things'), - '$personal' => t('Personal'), + '$basic' => t('Basic'), '$location' => t('Location'), '$relation' => t('Relationship'), '$miscellaneous'=> t('Miscellaneous'), @@ -801,6 +841,11 @@ class Profiles extends \Zotlabs\Web\Controller { '$update' => t('Update'), '$delete' => t('Delete'), '$cancel' => t('Cancel'), + + '$show_presence' => $show_presence, + '$suggestme' => $suggestme, + '$profile_in_dir' => $profile_in_dir, + )); $arr = array('profile' => $r[0], 'entry' => $o); diff --git a/Zotlabs/Module/Regate.php b/Zotlabs/Module/Regate.php index 462c997ff..33bb8d957 100644 --- a/Zotlabs/Module/Regate.php +++ b/Zotlabs/Module/Regate.php @@ -196,7 +196,7 @@ class Regate extends \Zotlabs\Web\Controller { if ($invite_channel) { $f = Connect::connect($new_channel['channel'], $invite_channel['xchan_addr']); if ($f['success']) { - $can_view_stream = their_perms_contains($channel_id, $f['abook']['abook_xchan'], 'view_stream'); + $can_view_stream = intval(get_abconfig($channel_id, $f['abook']['abook_xchan'], 'their_perms', 'view_stream')); // If we can view their stream, pull in some posts if ($can_view_stream) { Master::Summon(['Onepoll', $f['abook']['abook_id']]); diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php index e95752338..914523960 100644 --- a/Zotlabs/Module/Settings/Channel.php +++ b/Zotlabs/Module/Settings/Channel.php @@ -2,6 +2,10 @@ namespace Zotlabs\Module\Settings; +use App; +use Zotlabs\Access\PermissionLimits; +use Zotlabs\Access\PermissionRoles; +use Zotlabs\Daemon\Master; use Zotlabs\Lib\Apps; use Zotlabs\Lib\Libsync; @@ -10,602 +14,266 @@ require_once('include/selectors.php'); class Channel { - function post() { - $channel = \App::get_channel(); - check_form_security_token_redirectOnErr('/settings', 'settings'); - call_hooks('settings_post', $_POST); - $set_perms = ''; - - $role = ((x($_POST,'permissions_role')) ? notags(trim($_POST['permissions_role'])) : ''); - $oldrole = get_pconfig(local_channel(),'system','permissions_role'); - - // This mapping can be removed after 3.4 release - if($oldrole === 'social_party') { - $oldrole = 'social_federation'; - } - - if(($role != $oldrole) || ($role === 'custom')) { - - if($role === 'custom') { - $hide_presence = (((x($_POST,'hide_presence')) && (intval($_POST['hide_presence']) == 1)) ? 1: 0); - $publish = (((x($_POST,'profile_in_directory')) && (intval($_POST['profile_in_directory']) == 1)) ? 1: 0); - $def_group = ((x($_POST,'group-selection')) ? notags(trim($_POST['group-selection'])) : ''); - $r = q("update channel set channel_default_group = '%s' where channel_id = %d", - dbesc($def_group), - intval(local_channel()) - ); - - $global_perms = \Zotlabs\Access\Permissions::Perms(); - - foreach($global_perms as $k => $v) { - \Zotlabs\Access\PermissionLimits::Set(local_channel(),$k,intval($_POST[$k])); - } - $acl = new \Zotlabs\Access\AccessList($channel); - $acl->set_from_array($_POST); - $x = $acl->get(); - - $r = q("update channel set channel_allow_cid = '%s', channel_allow_gid = '%s', - channel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d", - dbesc($x['allow_cid']), - dbesc($x['allow_gid']), - dbesc($x['deny_cid']), - dbesc($x['deny_gid']), - intval(local_channel()) - ); - } - else { - $role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($_POST['permissions_role']); - if(! $role_permissions) { - notice('Permissions category could not be found.'); - return; - } - $hide_presence = 1 - (intval($role_permissions['online'])); - if($role_permissions['default_collection']) { - $r = q("select hash from pgrp where uid = %d and gname = '%s' limit 1", - intval(local_channel()), - dbesc( t('Friends') ) - ); - if(! $r) { - require_once('include/group.php'); - group_add(local_channel(), t('Friends')); - group_add_member(local_channel(),t('Friends'),$channel['channel_hash']); - $r = q("select hash from pgrp where uid = %d and gname = '%s' limit 1", - intval(local_channel()), - dbesc( t('Friends') ) - ); - } - if($r) { - q("update channel set channel_default_group = '%s', channel_allow_gid = '%s', channel_allow_cid = '', channel_deny_gid = '', channel_deny_cid = '' where channel_id = %d", - dbesc($r[0]['hash']), - dbesc('<' . $r[0]['hash'] . '>'), - intval(local_channel()) - ); - } - else { - notice( sprintf('Default privacy group \'%s\' not found. Please create and re-submit permission change.', t('Friends')) . EOL); - return; - } - } - // no default collection - else { - q("update channel set channel_default_group = '', channel_allow_gid = '', channel_allow_cid = '', channel_deny_gid = '', - channel_deny_cid = '' where channel_id = %d", - intval(local_channel()) - ); - } - - if($role_permissions['perms_connect']) { - $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']); - foreach($x as $k => $v) { - set_abconfig(local_channel(),$channel['channel_hash'],'my_perms',$k, $v); - if($role_permissions['perms_auto']) { - set_pconfig(local_channel(),'autoperms',$k,$v); - } - else { - del_pconfig(local_channel(),'autoperms',$k); - } - } - } - - if($role_permissions['limits']) { - foreach($role_permissions['limits'] as $k => $v) { - \Zotlabs\Access\PermissionLimits::Set(local_channel(),$k,$v); - } - } - if(array_key_exists('directory_publish',$role_permissions)) { - $publish = intval($role_permissions['directory_publish']); - } - } - - set_pconfig(local_channel(),'system','hide_online_status',$hide_presence); - set_pconfig(local_channel(),'system','permissions_role',$role); - } - - $username = ((x($_POST,'username')) ? notags(trim($_POST['username'])) : ''); - $timezone = ((x($_POST,'timezone_select')) ? notags(trim($_POST['timezone_select'])) : ''); - $defloc = ((x($_POST,'defloc')) ? notags(trim($_POST['defloc'])) : ''); - $openid = ((x($_POST,'openid_url')) ? notags(trim($_POST['openid_url'])) : ''); - $maxreq = ((x($_POST,'maxreq')) ? intval($_POST['maxreq']) : 0); - $expire = ((x($_POST,'expire')) ? intval($_POST['expire']) : 0); - $evdays = ((x($_POST,'evdays')) ? intval($_POST['evdays']) : 3); - $photo_path = ((x($_POST,'photo_path')) ? escape_tags(trim($_POST['photo_path'])) : ''); - $attach_path = ((x($_POST,'attach_path')) ? escape_tags(trim($_POST['attach_path'])) : ''); - - $expire_items = ((x($_POST,'expire_items')) ? intval($_POST['expire_items']) : 0); - $expire_starred = ((x($_POST,'expire_starred')) ? intval($_POST['expire_starred']) : 0); - $expire_photos = ((x($_POST,'expire_photos'))? intval($_POST['expire_photos']) : 0); - $expire_network_only = ((x($_POST,'expire_network_only'))? intval($_POST['expire_network_only']) : 0); - - $allow_location = (((x($_POST,'allow_location')) && (intval($_POST['allow_location']) == 1)) ? 1: 0); - - $blocktags = (((x($_POST,'blocktags')) && (intval($_POST['blocktags']) == 1)) ? 0: 1); // this setting is inverted! - $unkmail = (((x($_POST,'unkmail')) && (intval($_POST['unkmail']) == 1)) ? 1: 0); - $cntunkmail = ((x($_POST,'cntunkmail')) ? intval($_POST['cntunkmail']) : 0); - $suggestme = ((x($_POST,'suggestme')) ? intval($_POST['suggestme']) : 0); - $autoperms = ((x($_POST,'autoperms')) ? intval($_POST['autoperms']) : 0); - - $post_newfriend = (($_POST['post_newfriend'] == 1) ? 1: 0); - $post_joingroup = (($_POST['post_joingroup'] == 1) ? 1: 0); - $post_profilechange = (($_POST['post_profilechange'] == 1) ? 1: 0); - $adult = (($_POST['adult'] == 1) ? 1 : 0); - $defpermcat = ((x($_POST,'defpermcat')) ? notags(trim($_POST['defpermcat'])) : 'default'); - - $mailhost = ((array_key_exists('mailhost',$_POST)) ? notags(trim($_POST['mailhost'])) : ''); - - $pageflags = $channel['channel_pageflags']; - $existing_adult = (($pageflags & PAGE_ADULT) ? 1 : 0); - if($adult != $existing_adult) + $channel = App::get_channel(); + $role = ((x($_POST, 'permissions_role')) ? notags(trim($_POST['permissions_role'])) : ''); + $timezone = ((x($_POST, 'timezone_select')) ? notags(trim($_POST['timezone_select'])) : ''); + $defloc = ((x($_POST, 'defloc')) ? notags(trim($_POST['defloc'])) : ''); + $evdays = ((x($_POST, 'evdays')) ? intval($_POST['evdays']) : 3); + $photo_path = ((x($_POST, 'photo_path')) ? escape_tags(trim($_POST['photo_path'])) : ''); + $attach_path = ((x($_POST, 'attach_path')) ? escape_tags(trim($_POST['attach_path'])) : ''); + $allow_location = (((x($_POST, 'allow_location')) && (intval($_POST['allow_location']) == 1)) ? 1 : 0); + $post_newfriend = (($_POST['post_newfriend'] == 1) ? 1 : 0); + $post_joingroup = (($_POST['post_joingroup'] == 1) ? 1 : 0); + $post_profilechange = (($_POST['post_profilechange'] == 1) ? 1 : 0); + $adult = (($_POST['adult'] == 1) ? 1 : 0); + $mailhost = ((array_key_exists('mailhost', $_POST)) ? notags(trim($_POST['mailhost'])) : ''); + $pageflags = $channel['channel_pageflags']; + $existing_adult = (($pageflags & PAGE_ADULT) ? 1 : 0); + $expire = ((x($_POST, 'expire')) ? intval($_POST['expire']) : 0); + + if ($adult != $existing_adult) { $pageflags = ($pageflags ^ PAGE_ADULT); - + } $notify = 0; - - if(x($_POST,'notify1')) + if (x($_POST, 'notify1')) $notify += intval($_POST['notify1']); - if(x($_POST,'notify2')) + if (x($_POST, 'notify2')) $notify += intval($_POST['notify2']); - if(x($_POST,'notify3')) + if (x($_POST, 'notify3')) $notify += intval($_POST['notify3']); - if(x($_POST,'notify4')) + if (x($_POST, 'notify4')) $notify += intval($_POST['notify4']); - if(x($_POST,'notify5')) + if (x($_POST, 'notify5')) $notify += intval($_POST['notify5']); - if(x($_POST,'notify6')) + if (x($_POST, 'notify6')) $notify += intval($_POST['notify6']); - if(x($_POST,'notify7')) + if (x($_POST, 'notify7')) $notify += intval($_POST['notify7']); - if(x($_POST,'notify8')) + if (x($_POST, 'notify8')) $notify += intval($_POST['notify8']); $vnotify = 0; - - if(x($_POST,'vnotify1')) + if (x($_POST, 'vnotify1')) $vnotify += intval($_POST['vnotify1']); - if(x($_POST,'vnotify2')) + if (x($_POST, 'vnotify2')) $vnotify += intval($_POST['vnotify2']); - if(x($_POST,'vnotify3')) + if (x($_POST, 'vnotify3')) $vnotify += intval($_POST['vnotify3']); - if(x($_POST,'vnotify4')) + if (x($_POST, 'vnotify4')) $vnotify += intval($_POST['vnotify4']); - if(x($_POST,'vnotify5')) + if (x($_POST, 'vnotify5')) $vnotify += intval($_POST['vnotify5']); - if(x($_POST,'vnotify6')) + if (x($_POST, 'vnotify6')) $vnotify += intval($_POST['vnotify6']); - if(x($_POST,'vnotify7')) + if (x($_POST, 'vnotify7')) $vnotify += intval($_POST['vnotify7']); - if(x($_POST,'vnotify8')) + if (x($_POST, 'vnotify8')) $vnotify += intval($_POST['vnotify8']); - if(x($_POST,'vnotify9')) + if (x($_POST, 'vnotify9')) $vnotify += intval($_POST['vnotify9']); - if(x($_POST,'vnotify10')) + if (x($_POST, 'vnotify10')) $vnotify += intval($_POST['vnotify10']); - if(x($_POST,'vnotify11') && is_site_admin()) + if (x($_POST, 'vnotify11') && is_site_admin()) $vnotify += intval($_POST['vnotify11']); - if(x($_POST,'vnotify12')) + if (x($_POST, 'vnotify12')) $vnotify += intval($_POST['vnotify12']); - if(x($_POST,'vnotify13')) + if (x($_POST, 'vnotify13')) $vnotify += intval($_POST['vnotify13']); - if(x($_POST,'vnotify14')) + if (x($_POST, 'vnotify14')) $vnotify += intval($_POST['vnotify14']); - if(x($_POST,'vnotify15')) + if (x($_POST, 'vnotify15')) $vnotify += intval($_POST['vnotify15']); - $always_show_in_notices = x($_POST, 'always_show_in_notices') ? 1 : 0; - $update_notices_per_parent = x($_POST, 'update_notices_per_parent') ? 1 : 0; + $always_show_in_notices = ((x($_POST, 'always_show_in_notices')) ? 1 : 0); + $update_notices_per_parent = ((x($_POST, 'update_notices_per_parent')) ? 1 : 0); - $err = ''; + if ($timezone !== $channel['channel_timezone']) { + if (strlen($timezone)) + date_default_timezone_set($timezone); + } - $name_change = false; + if ($role !== get_pconfig(local_channel(), 'system', 'permissions_role')) { + $role_permissions = PermissionRoles::role_perms($_POST['permissions_role']); - if($username != $channel['channel_name']) { - $name_change = true; - require_once('include/channel.php'); - $err = validate_channelname($username); - if($err) { - notice($err); - return; + if (isset($role_permissions['limits'])) { + foreach ($role_permissions['limits'] as $k => $v) { + PermissionLimits::Set(local_channel(), $k, $v); + } } - } - if($timezone != $channel['channel_timezone']) { - if(strlen($timezone)) - date_default_timezone_set($timezone); + set_pconfig(local_channel(), 'system', 'group_actor', 0); + if (isset($role_permissions['channel_type']) && $role_permissions['channel_type'] === 'group') { + set_pconfig(local_channel(), 'system', 'group_actor', 1); + } } - set_pconfig(local_channel(),'system','use_browser_location',$allow_location); - set_pconfig(local_channel(),'system','suggestme', $suggestme); - set_pconfig(local_channel(),'system','post_newfriend', $post_newfriend); - set_pconfig(local_channel(),'system','post_joingroup', $post_joingroup); - set_pconfig(local_channel(),'system','post_profilechange', $post_profilechange); - set_pconfig(local_channel(),'system','blocktags',$blocktags); - set_pconfig(local_channel(),'system','vnotify',$vnotify); - set_pconfig(local_channel(),'system','always_show_in_notices',$always_show_in_notices); - set_pconfig(local_channel(),'system','update_notices_per_parent',$update_notices_per_parent); - set_pconfig(local_channel(),'system','evdays',$evdays); - set_pconfig(local_channel(),'system','photo_path',$photo_path); - set_pconfig(local_channel(),'system','attach_path',$attach_path); - set_pconfig(local_channel(),'system','default_permcat',$defpermcat); - set_pconfig(local_channel(),'system','email_notify_host',$mailhost); - set_pconfig(local_channel(),'system','autoperms',$autoperms); - - $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d $set_perms where channel_id = %d", - dbesc($username), + set_pconfig(local_channel(), 'system', 'permissions_role', $role); + set_pconfig(local_channel(), 'system', 'use_browser_location', $allow_location); + set_pconfig(local_channel(), 'system', 'post_newfriend', $post_newfriend); + set_pconfig(local_channel(), 'system', 'post_joingroup', $post_joingroup); + set_pconfig(local_channel(), 'system', 'post_profilechange', $post_profilechange); + set_pconfig(local_channel(), 'system', 'vnotify', $vnotify); + set_pconfig(local_channel(), 'system', 'always_show_in_notices', $always_show_in_notices); + set_pconfig(local_channel(), 'system', 'update_notices_per_parent', $update_notices_per_parent); + set_pconfig(local_channel(), 'system', 'evdays', $evdays); + set_pconfig(local_channel(), 'system', 'photo_path', $photo_path); + set_pconfig(local_channel(), 'system', 'attach_path', $attach_path); + set_pconfig(local_channel(), 'system', 'email_notify_host', $mailhost); + + $r = q("update channel set channel_pageflags = %d, channel_timezone = '%s', + channel_location = '%s', channel_notifyflags = %d, channel_expire_days = %d + where channel_id = %d", intval($pageflags), dbesc($timezone), dbesc($defloc), intval($notify), - intval($unkmail), - intval($maxreq), intval($expire), intval(local_channel()) ); - if($r) - info( t('Settings updated.') . EOL); - - if(! is_null($publish)) { - $r = q("UPDATE profile SET publish = %d WHERE is_default = 1 AND uid = %d", - intval($publish), - intval(local_channel()) - ); - } - - if($name_change) { - // change name on all associated xchans by matching the url - $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_url = '%s'", - dbesc($username), - dbesc(datetime_convert()), - dbesc(z_root() . '/channel/' . $channel['channel_address']) - ); - $r = q("update profile set fullname = '%s' where uid = %d and is_default = 1", - dbesc($username), - intval($channel['channel_id']) - ); - } - - \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); + if ($r) + info(t('Settings updated.') . EOL); + Master::Summon(['Directory', local_channel()]); Libsync::build_sync_packet(); - - if($email_changed && \App::$config['system']['register_policy'] == REGISTER_VERIFY) { + if ($email_changed && App::$config['system']['register_policy'] == REGISTER_VERIFY) { // FIXME - set to un-verified, blocked and redirect to logout // Q: Why? Are we verifying people or email addresses? // A: the policy is to verify email addresses } - goaway(z_root() . '/settings' ); + goaway(z_root() . '/settings'); return; // NOTREACHED } function get() { - require_once('include/acl_selectors.php'); - require_once('include/permissions.php'); - - - $yes_no = array(t('No'),t('Yes')); - - - $p = q("SELECT * FROM profile WHERE is_default = 1 AND uid = %d LIMIT 1", - intval(local_channel()) - ); - if(count($p)) - $profile = $p[0]; - - load_pconfig(local_channel(),'expire'); - - $channel = \App::get_channel(); - - $global_perms = \Zotlabs\Access\Permissions::Perms(); - - $permiss = array(); - - $perm_opts = array( - array( t('Nobody except yourself'), 0), - array( t('Only those you specifically allow'), PERMS_SPECIFIC), - array( t('Approved connections'), PERMS_CONTACTS), - array( t('Any connections'), PERMS_PENDING), - array( t('Anybody on this website'), PERMS_SITE), - array( t('Anybody in this network'), PERMS_NETWORK), - array( t('Anybody authenticated'), PERMS_AUTHED), - array( t('Anybody on the internet'), PERMS_PUBLIC) - ); - - $limits = \Zotlabs\Access\PermissionLimits::Get(local_channel()); - $anon_comments = get_config('system','anonymous_comments',true); - - foreach($global_perms as $k => $perm) { - $options = array(); - $can_be_public = ((strstr($k,'view') || ($k === 'post_comments' && $anon_comments)) ? true : false); - foreach($perm_opts as $opt) { - if($opt[1] == PERMS_PUBLIC && (! $can_be_public)) - continue; - $options[$opt[1]] = $opt[0]; - } - $permiss[] = array($k,$perm,$limits[$k],'',$options); - } - - // logger('permiss: ' . print_r($permiss,true)); - - $username = $channel['channel_name']; - $nickname = $channel['channel_address']; - $timezone = $channel['channel_timezone']; - $notify = $channel['channel_notifyflags']; - $defloc = $channel['channel_location']; - - $maxreq = $channel['channel_max_friend_req']; - $expire = $channel['channel_expire_days']; - $adult_flag = intval($channel['channel_pageflags'] & PAGE_ADULT); - $sys_expire = get_config('system','default_expire_days'); - -// $unkmail = \App::$user['unkmail']; -// $cntunkmail = \App::$user['cntunkmail']; - - $hide_presence = intval(get_pconfig(local_channel(), 'system','hide_online_status')); - - - $expire_items = get_pconfig(local_channel(), 'expire','items'); - $expire_items = (($expire_items===false)? '1' : $expire_items); // default if not set: 1 - - $expire_notes = get_pconfig(local_channel(), 'expire','notes'); - $expire_notes = (($expire_notes===false)? '1' : $expire_notes); // default if not set: 1 - - $expire_starred = get_pconfig(local_channel(), 'expire','starred'); - $expire_starred = (($expire_starred===false)? '1' : $expire_starred); // default if not set: 1 - - $expire_photos = get_pconfig(local_channel(), 'expire','photos'); - $expire_photos = (($expire_photos===false)? '0' : $expire_photos); // default if not set: 0 - - $expire_network_only = get_pconfig(local_channel(), 'expire','network_only'); - $expire_network_only = (($expire_network_only===false)? '0' : $expire_network_only); // default if not set: 0 - - - $suggestme = get_pconfig(local_channel(), 'system','suggestme'); - $suggestme = (($suggestme===false)? '0': $suggestme); // default if not set: 0 - - $post_newfriend = get_pconfig(local_channel(), 'system','post_newfriend'); - $post_newfriend = (($post_newfriend===false)? '0': $post_newfriend); // default if not set: 0 - - $post_joingroup = get_pconfig(local_channel(), 'system','post_joingroup'); - $post_joingroup = (($post_joingroup===false)? '0': $post_joingroup); // default if not set: 0 - - $post_profilechange = get_pconfig(local_channel(), 'system','post_profilechange'); - $post_profilechange = (($post_profilechange===false)? '0': $post_profilechange); // default if not set: 0 - - $blocktags = get_pconfig(local_channel(),'system','blocktags'); - $blocktags = (($blocktags===false) ? '0' : $blocktags); - - $timezone = date_default_timezone_get(); - - $opt_tpl = get_markup_template("field_checkbox.tpl"); - if(get_config('system','publish_all')) { - $profile_in_dir = ''; - } - else { - $profile_in_dir = replace_macros($opt_tpl,array( - '$field' => array('profile_in_directory', t('Publish your default profile in the network directory'), $profile['publish'], '', $yes_no), - )); - } - - $suggestme = replace_macros($opt_tpl,array( - '$field' => array('suggestme', t('Allow us to suggest you as a potential friend to new members?'), $suggestme, '', $yes_no), - - )); - - $subdir = ((strlen(\App::get_path())) ? '
' . t('or') . ' ' . z_root() . '/channel/' . $nickname : ''); - - $webbie = $nickname . '@' . \App::get_hostname(); - $intl_nickname = unpunify($nickname) . '@' . unpunify(\App::get_hostname()); - - - $tpl_addr = get_markup_template("settings_nick_set.tpl"); - - $prof_addr = replace_macros($tpl_addr,array( - '$desc' => t('Your channel address is'), + load_pconfig(local_channel()); + + $channel = App::get_channel(); + $nickname = $channel['channel_address']; + $timezone = $channel['channel_timezone']; + $notify = $channel['channel_notifyflags']; + $defloc = $channel['channel_location']; + $adult_flag = intval($channel['channel_pageflags'] & PAGE_ADULT); + $post_newfriend = get_pconfig(local_channel(), 'system', 'post_newfriend'); + $post_newfriend = (($post_newfriend === false) ? '0' : $post_newfriend); // default if not set: 0 + $post_joingroup = get_pconfig(local_channel(), 'system', 'post_joingroup'); + $post_joingroup = (($post_joingroup === false) ? '0' : $post_joingroup); // default if not set: 0 + $post_profilechange = get_pconfig(local_channel(), 'system', 'post_profilechange'); + $post_profilechange = (($post_profilechange === false) ? '0' : $post_profilechange); // default if not set: 0 + $subdir = ((strlen(App::get_path())) ? '
' . t('or') . ' ' . z_root() . '/channel/' . $nickname : ''); + $webbie = $nickname . '@' . App::get_hostname(); + $intl_nickname = unpunify($nickname) . '@' . unpunify(App::get_hostname()); + $disable_discover_tab = intval(get_config('system', 'disable_discover_tab', 1)) == 1; + $site_firehose = intval(get_config('system', 'site_firehose', 0)) == 1; + + $expire = $channel['channel_expire_days']; + $sys_expire = get_config('system', 'default_expire_days'); + + $tpl_addr = get_markup_template("settings_nick_set.tpl"); + $prof_addr = replace_macros($tpl_addr, [ + '$desc' => t('Your channel address is'), '$nickname' => (($intl_nickname === $webbie) ? $webbie : $intl_nickname . ' (' . $webbie . ')'), - '$subdir' => $subdir, - '$davdesc' => t('Your files/photos are accessible via WebDAV at'), - '$davpath' => z_root() . '/dav/' . $nickname, - '$basepath' => \App::get_hostname() - )); - - - - $pcat = new \Zotlabs\Lib\Permcat(local_channel()); - $pcatlist = $pcat->listing(); - $permcats = []; - if($pcatlist) { - foreach($pcatlist as $pc) { - $permcats[$pc['name']] = $pc['localname']; - } - } - - $default_permcat = get_pconfig(local_channel(),'system','default_permcat','default'); - - - $stpl = get_markup_template('settings.tpl'); - - $acl = new \Zotlabs\Access\AccessList($channel); - $perm_defaults = $acl->get(); - - require_once('include/group.php'); - $group_select = mini_group_select(local_channel(),$channel['channel_default_group']); - - $evdays = get_pconfig(local_channel(),'system','evdays'); - if(! $evdays) + '$subdir' => $subdir, + '$davdesc' => t('Your files/photos are accessible via WebDAV at'), + '$davpath' => z_root() . '/dav/' . $nickname, + '$basepath' => App::get_hostname() + ]); + + $evdays = get_pconfig(local_channel(), 'system', 'evdays'); + if (!$evdays) $evdays = 3; - $permissions_role = get_pconfig(local_channel(),'system','permissions_role'); - if(! $permissions_role) - $permissions_role = 'custom'; - // compatibility mapping - can be removed after 3.4 release - if($permissions_role === 'social_party') - $permissions_role = 'social_federation'; + $always_show_in_notices = get_pconfig(local_channel(), 'system', 'always_show_in_notices'); + $update_notices_per_parent = get_pconfig(local_channel(), 'system', 'update_notices_per_parent', 1); - if(in_array($permissions_role,['forum','repository'])) - $autoperms = replace_macros(get_markup_template('field_checkbox.tpl'), [ - '$field' => [ 'autoperms',t('Automatic membership approval'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('If enabled, connection requests will be approved without your interaction'), $yes_no ]]); - else - $autoperms = ''; + $vnotify = get_pconfig(local_channel(), 'system', 'vnotify'); + if ($vnotify === false) + $vnotify = (-1); - $permissions_set = (($permissions_role != 'custom') ? true : false); + $permissions_role = get_pconfig(local_channel(), 'system', 'permissions_role'); + if (!$permissions_role) { + $permissions_role = 'custom'; + } - $perm_roles = \Zotlabs\Access\PermissionRoles::roles(); + $perm_roles = PermissionRoles::channel_roles(); - $always_show_in_notices = get_pconfig(local_channel(),'system','always_show_in_notices'); - $update_notices_per_parent = get_pconfig(local_channel(), 'system', 'update_notices_per_parent', 1); - $vnotify = get_pconfig(local_channel(),'system','vnotify'); + $plugin = ['basic' => '', 'notify' => '']; + call_hooks('channel_settings', $plugin); - if($vnotify === false) - $vnotify = (-1); + $yes_no = [t('No'), t('Yes')]; - $plugin = [ 'basic' => '', 'security' => '', 'notify' => '' ]; - call_hooks('channel_settings',$plugin); - - $disable_discover_tab = intval(get_config('system','disable_discover_tab',1)) == 1; - $site_firehose = intval(get_config('system','site_firehose',0)) == 1; - - - $o .= replace_macros($stpl,array( - '$ptitle' => t('Channel Settings'), - - '$submit' => t('Submit'), - '$baseurl' => z_root(), - '$uid' => local_channel(), - '$form_security_token' => get_form_security_token("settings"), - '$nickname_block' => $prof_addr, - '$h_basic' => t('Basic Settings'), - '$username' => array('username', t('Full Name:'), $username,''), - '$email' => array('email', t('Email Address:'), $email, ''), - '$timezone' => array('timezone_select' , t('Your Timezone:'), $timezone, '', get_timezones()), - '$defloc' => array('defloc', t('Default Post Location:'), $defloc, t('Geographical location to display on your posts')), - '$allowloc' => array('allow_location', t('Use Browser Location:'), ((get_pconfig(local_channel(),'system','use_browser_location')) ? 1 : ''), '', $yes_no), - - '$adult' => array('adult', t('Adult Content'), $adult_flag, t('This channel frequently or regularly publishes adult content. (Please tag any adult material and/or nudity with #NSFW)'), $yes_no), - - '$h_prv' => t('Security and Privacy Settings'), - '$permissions_set' => $permissions_set, - '$perms_set_msg' => t('Your permissions are already configured. Click to view/adjust'), - - '$hide_presence' => array('hide_presence', t('Hide my online presence'),$hide_presence, t('Prevents displaying in your profile that you are online'), $yes_no), - - '$lbl_pmacro' => t('Simple Privacy Settings:'), - '$pmacro3' => t('Very Public - extremely permissive (should be used with caution)'), - '$pmacro2' => t('Typical - default public, privacy when desired (similar to social network permissions but with improved privacy)'), - '$pmacro1' => t('Private - default private, never open or public'), - '$pmacro0' => t('Blocked - default blocked to/from everybody'), - '$permiss_arr' => $permiss, - '$blocktags' => array('blocktags',t('Allow others to tag your posts'), 1-$blocktags, t('Often used by the community to retro-actively flag inappropriate content'), $yes_no), - - '$lbl_p2macro' => t('Channel Permission Limits'), - - '$expire' => array('expire',t('Expire other channel content after this many days'),$expire, t('0 or blank to use the website limit.') . ' ' . ((intval($sys_expire)) ? sprintf( t('This website expires after %d days.'),intval($sys_expire)) : t('This website does not expire imported content.')) . ' ' . t('The website limit takes precedence if lower than your limit.')), - '$maxreq' => array('maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']) , t('May reduce spam activity')), - '$permissions' => t('Default Privacy Group'), - '$permdesc' => t("\x28click to open/close\x29"), - '$aclselect' => populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))), - - '$allow_cid' => acl2json($perm_defaults['allow_cid']), - '$allow_gid' => acl2json($perm_defaults['allow_gid']), - '$deny_cid' => acl2json($perm_defaults['deny_cid']), - '$deny_gid' => acl2json($perm_defaults['deny_gid']), - '$suggestme' => $suggestme, - '$group_select' => $group_select, - '$role' => array('permissions_role' , t('Channel role and privacy'), $permissions_role, '', $perm_roles), - '$defpermcat' => [ 'defpermcat', t('Default permissions category'), $default_permcat, '', $permcats ], - '$permcat_enable' => Apps::system_app_installed(local_channel(), 'Permission Categories'), - '$profile_in_dir' => $profile_in_dir, - '$hide_friends' => $hide_friends, - '$hide_wall' => $hide_wall, - '$unkmail' => $unkmail, - '$cntunkmail' => array('cntunkmail', t('Maximum private messages per day from unknown people:'), intval($channel['channel_max_anon_mail']) ,t("Useful to reduce spamming")), - - '$autoperms' => $autoperms, - '$h_not' => t('Notification Settings'), - '$activity_options' => t('By default post a status message when:'), - '$post_newfriend' => array('post_newfriend', t('accepting a friend request'), $post_newfriend, '', $yes_no), - '$post_joingroup' => array('post_joingroup', t('joining a forum/community'), $post_joingroup, '', $yes_no), - '$post_profilechange' => array('post_profilechange', t('making an interesting profile change'), $post_profilechange, '', $yes_no), - '$lbl_not' => t('Send a notification email when:'), - '$notify1' => array('notify1', t('You receive a connection request'), ($notify & NOTIFY_INTRO), NOTIFY_INTRO, '', $yes_no), - '$notify2' => array('notify2', t('Your connections are confirmed'), ($notify & NOTIFY_CONFIRM), NOTIFY_CONFIRM, '', $yes_no), - '$notify3' => array('notify3', t('Someone writes on your profile wall'), ($notify & NOTIFY_WALL), NOTIFY_WALL, '', $yes_no), - '$notify4' => array('notify4', t('Someone writes a followup comment'), ($notify & NOTIFY_COMMENT), NOTIFY_COMMENT, '', $yes_no), - '$notify5' => array('notify5', t('You receive a private message'), ($notify & NOTIFY_MAIL), NOTIFY_MAIL, '', $yes_no), - '$notify6' => array('notify6', t('You receive a friend suggestion'), ($notify & NOTIFY_SUGGEST), NOTIFY_SUGGEST, '', $yes_no), - '$notify7' => array('notify7', t('You are tagged in a post'), ($notify & NOTIFY_TAGSELF), NOTIFY_TAGSELF, '', $yes_no), - '$notify8' => array('notify8', t('You are poked/prodded/etc. in a post'), ($notify & NOTIFY_POKE), NOTIFY_POKE, '', $yes_no), - - '$notify9' => array('notify9', t('Someone likes your post/comment'), ($notify & NOTIFY_LIKE), NOTIFY_LIKE, '', $yes_no), - - - '$lbl_vnot' => t('Show visual notifications including:'), - - '$vnotify1' => array('vnotify1', t('Unseen stream activity'), ($vnotify & VNOTIFY_NETWORK), VNOTIFY_NETWORK, '', $yes_no), - '$vnotify2' => array('vnotify2', t('Unseen channel activity'), ($vnotify & VNOTIFY_CHANNEL), VNOTIFY_CHANNEL, '', $yes_no), - '$vnotify3' => array('vnotify3', t('Unseen private messages'), ($vnotify & VNOTIFY_MAIL), VNOTIFY_MAIL, t('Recommended'), $yes_no), - '$vnotify4' => array('vnotify4', t('Upcoming events'), ($vnotify & VNOTIFY_EVENT), VNOTIFY_EVENT, '', $yes_no), - '$vnotify5' => array('vnotify5', t('Events today'), ($vnotify & VNOTIFY_EVENTTODAY), VNOTIFY_EVENTTODAY, '', $yes_no), - '$vnotify6' => array('vnotify6', t('Upcoming birthdays'), ($vnotify & VNOTIFY_BIRTHDAY), VNOTIFY_BIRTHDAY, t('Not available in all themes'), $yes_no), - '$vnotify7' => array('vnotify7', t('System (personal) notifications'), ($vnotify & VNOTIFY_SYSTEM), VNOTIFY_SYSTEM, '', $yes_no), - '$vnotify8' => array('vnotify8', t('System info messages'), ($vnotify & VNOTIFY_INFO), VNOTIFY_INFO, t('Recommended'), $yes_no), - '$vnotify9' => array('vnotify9', t('System critical alerts'), ($vnotify & VNOTIFY_ALERT), VNOTIFY_ALERT, t('Recommended'), $yes_no), - '$vnotify10' => array('vnotify10', t('New connections'), ($vnotify & VNOTIFY_INTRO), VNOTIFY_INTRO, t('Recommended'), $yes_no), - '$vnotify11' => ((is_site_admin()) ? array('vnotify11', t('System Registrations'), ($vnotify & VNOTIFY_REGISTER), VNOTIFY_REGISTER, '', $yes_no) : array()), - '$vnotify12' => array('vnotify12', t('Unseen shared files'), ($vnotify & VNOTIFY_FILES), VNOTIFY_FILES, '', $yes_no), - '$vnotify13' => ((($disable_discover_tab && !$site_firehose) || !Apps::system_app_installed(local_channel(), 'Public Stream')) ? array() : array('vnotify13', t('Unseen public stream activity'), ($vnotify & VNOTIFY_PUBS), VNOTIFY_PUBS, '', $yes_no)), - '$vnotify14' => array('vnotify14', t('Unseen likes and dislikes'), ($vnotify & VNOTIFY_LIKE), VNOTIFY_LIKE, '', $yes_no), - '$vnotify15' => array('vnotify15', t('Unseen forum posts'), ($vnotify & VNOTIFY_FORUMS), VNOTIFY_FORUMS, '', $yes_no), - '$mailhost' => [ 'mailhost', t('Email notification hub (hostname)'), get_pconfig(local_channel(),'system','email_notify_host',\App::get_hostname()), sprintf( t('If your channel is mirrored to multiple hubs, set this to your preferred location. This will prevent duplicate email notifications. Example: %s'),\App::get_hostname()) ], - '$always_show_in_notices' => array('always_show_in_notices', t('Show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no), - '$update_notices_per_parent' => array('update_notices_per_parent', t('Mark all notices of the thread read if a notice is clicked'), $update_notices_per_parent, 1, t('If no, only the clicked notice will be marked read'), $yes_no), - '$desktop_notifications_info' => t('Desktop notifications are unavailable because the required browser permission has not been granted'), + $stpl = get_markup_template('settings.tpl'); + $o = replace_macros($stpl, [ + '$ptitle' => t('Channel Settings'), + '$submit' => t('Submit'), + '$baseurl' => z_root(), + '$uid' => local_channel(), + '$form_security_token' => get_form_security_token("settings"), + '$role' => ['permissions_role', t('Channel role'), $permissions_role, '', $perm_roles], + '$nickname_block' => $prof_addr, + '$h_basic' => t('Basic Settings'), + '$timezone' => ['timezone_select', t('Channel timezone:'), $timezone, '', get_timezones()], + '$defloc' => ['defloc', t('Default post location:'), $defloc, t('Geographical location to display on your posts')], + '$allowloc' => ['allow_location', t('Use browser location:'), ((get_pconfig(local_channel(), 'system', 'use_browser_location')) ? 1 : ''), '', $yes_no], + '$adult' => ['adult', t('Adult Content'), $adult_flag, t('This channel frequently or regularly publishes adult content')], + '$maxreq' => ['maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']), t('May reduce spam activity')], + '$h_not' => t('Notification Settings'), + '$activity_options' => t('By default post a status message when:'), + '$post_newfriend' => ['post_newfriend', t('accepting a friend request'), $post_newfriend, '', $yes_no], + '$post_joingroup' => ['post_joingroup', t('joining a forum/community'), $post_joingroup, '', $yes_no], + '$post_profilechange' => ['post_profilechange', t('making an interesting profile change'), $post_profilechange, '', $yes_no], + '$lbl_not' => t('Send a notification email when:'), + '$notify1' => ['notify1', t('You receive a connection request'), ($notify & NOTIFY_INTRO), NOTIFY_INTRO, '', $yes_no], + '$notify2' => ['notify2', t('Your connections are confirmed'), ($notify & NOTIFY_CONFIRM), NOTIFY_CONFIRM, '', $yes_no], + '$notify3' => ['notify3', t('Someone writes on your profile wall'), ($notify & NOTIFY_WALL), NOTIFY_WALL, '', $yes_no], + '$notify4' => ['notify4', t('Someone writes a followup comment'), ($notify & NOTIFY_COMMENT), NOTIFY_COMMENT, '', $yes_no], + '$notify5' => ['notify5', t('You receive a private message'), ($notify & NOTIFY_MAIL), NOTIFY_MAIL, '', $yes_no], + '$notify6' => ['notify6', t('You receive a friend suggestion'), ($notify & NOTIFY_SUGGEST), NOTIFY_SUGGEST, '', $yes_no], + '$notify7' => ['notify7', t('You are tagged in a post'), ($notify & NOTIFY_TAGSELF), NOTIFY_TAGSELF, '', $yes_no], + '$notify8' => ['notify8', t('You are poked/prodded/etc. in a post'), ($notify & NOTIFY_POKE), NOTIFY_POKE, '', $yes_no], + '$notify9' => ['notify9', t('Someone likes your post/comment'), ($notify & NOTIFY_LIKE), NOTIFY_LIKE, '', $yes_no], + '$lbl_vnot' => t('Show visual notifications including:'), + '$vnotify1' => ['vnotify1', t('Unseen stream activity'), ($vnotify & VNOTIFY_NETWORK), VNOTIFY_NETWORK, '', $yes_no], + '$vnotify2' => ['vnotify2', t('Unseen channel activity'), ($vnotify & VNOTIFY_CHANNEL), VNOTIFY_CHANNEL, '', $yes_no], + '$vnotify3' => ['vnotify3', t('Unseen private messages'), ($vnotify & VNOTIFY_MAIL), VNOTIFY_MAIL, t('Recommended'), $yes_no], + '$vnotify4' => ['vnotify4', t('Upcoming events'), ($vnotify & VNOTIFY_EVENT), VNOTIFY_EVENT, '', $yes_no], + '$vnotify5' => ['vnotify5', t('Events today'), ($vnotify & VNOTIFY_EVENTTODAY), VNOTIFY_EVENTTODAY, '', $yes_no], + '$vnotify6' => ['vnotify6', t('Upcoming birthdays'), ($vnotify & VNOTIFY_BIRTHDAY), VNOTIFY_BIRTHDAY, t('Not available in all themes'), $yes_no], + '$vnotify7' => ['vnotify7', t('System (personal) notifications'), ($vnotify & VNOTIFY_SYSTEM), VNOTIFY_SYSTEM, '', $yes_no], + '$vnotify8' => ['vnotify8', t('System info messages'), ($vnotify & VNOTIFY_INFO), VNOTIFY_INFO, t('Recommended'), $yes_no], + '$vnotify9' => ['vnotify9', t('System critical alerts'), ($vnotify & VNOTIFY_ALERT), VNOTIFY_ALERT, t('Recommended'), $yes_no], + '$vnotify10' => ['vnotify10', t('New connections'), ($vnotify & VNOTIFY_INTRO), VNOTIFY_INTRO, t('Recommended'), $yes_no], + '$vnotify11' => ((is_site_admin()) ? ['vnotify11', t('System Registrations'), ($vnotify & VNOTIFY_REGISTER), VNOTIFY_REGISTER, '', $yes_no] : []), + '$vnotify12' => ['vnotify12', t('Unseen shared files'), ($vnotify & VNOTIFY_FILES), VNOTIFY_FILES, '', $yes_no], + '$vnotify13' => ((($disable_discover_tab && !$site_firehose) || !Apps::system_app_installed(local_channel(), 'Public Stream')) ? [] : ['vnotify13', t('Unseen public stream activity'), ($vnotify & VNOTIFY_PUBS), VNOTIFY_PUBS, '', $yes_no]), + '$vnotify14' => ['vnotify14', t('Unseen likes and dislikes'), ($vnotify & VNOTIFY_LIKE), VNOTIFY_LIKE, '', $yes_no], + '$vnotify15' => ['vnotify15', t('Unseen forum posts'), ($vnotify & VNOTIFY_FORUMS), VNOTIFY_FORUMS, '', $yes_no], + '$mailhost' => ['mailhost', t('Email notification hub (hostname)'), get_pconfig(local_channel(), 'system', 'email_notify_host', App::get_hostname()), sprintf(t('If your channel is mirrored to multiple hubs, set this to your preferred location. This will prevent duplicate email notifications. Example: %s'), App::get_hostname())], + '$always_show_in_notices' => ['always_show_in_notices', t('Show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no], + '$update_notices_per_parent' => ['update_notices_per_parent', t('Mark all notices of the thread read if a notice is clicked'), $update_notices_per_parent, 1, t('If no, only the clicked notice will be marked read'), $yes_no], + '$desktop_notifications_info' => t('Desktop notifications are unavailable because the required browser permission has not been granted'), '$desktop_notifications_request' => t('Grant permission'), - '$evdays' => array('evdays', t('Notify me of events this many days in advance'), $evdays, t('Must be greater than 0')), - '$basic_addon' => $plugin['basic'], - '$sec_addon' => $plugin['security'], - '$notify_addon' => $plugin['notify'], - - '$h_advn' => t('Advanced Account/Page Type Settings'), - '$h_descadvn' => t('Change the behaviour of this account for special situations'), - '$pagetype' => $pagetype, - '$lbl_misc' => t('Miscellaneous Settings'), - '$photo_path' => array('photo_path', t('Default photo upload folder'), get_pconfig(local_channel(),'system','photo_path'), t('%Y - current year, %m - current month')), - '$attach_path' => array('attach_path', t('Default file upload folder'), get_pconfig(local_channel(),'system','attach_path'), t('%Y - current year, %m - current month')), - '$removeme' => t('Remove Channel'), - '$removechannel' => t('Remove this channel.'), - )); - - call_hooks('settings_form',$o); - - //$o .= '' . "\r\n"; + '$evdays' => ['evdays', t('Notify me of events this many days in advance'), $evdays, t('Must be greater than 0')], + '$basic_addon' => $plugin['basic'], + '$notify_addon' => $plugin['notify'], + '$photo_path' => ['photo_path', t('Default photo upload folder'), get_pconfig(local_channel(), 'system', 'photo_path'), t('%Y - current year, %m - current month')], + '$attach_path' => ['attach_path', t('Default file upload folder'), get_pconfig(local_channel(), 'system', 'attach_path'), t('%Y - current year, %m - current month')], + '$removeme' => t('Remove Channel'), + '$removechannel' => t('Remove this channel.'), + '$expire' => ['expire', t('Expire other channel content after this many days'), $expire, t('0 or blank to use the website limit.') . ' ' . ((intval($sys_expire)) ? sprintf(t('This website expires after %d days.'), intval($sys_expire)) : t('This website does not expire imported content.')) . ' ' . t('The website limit takes precedence if lower than your limit.')], + ]); + + call_hooks('settings_form', $o); return $o; } diff --git a/Zotlabs/Module/Settings/Privacy.php b/Zotlabs/Module/Settings/Privacy.php new file mode 100644 index 000000000..fbda78a6f --- /dev/null +++ b/Zotlabs/Module/Settings/Privacy.php @@ -0,0 +1,127 @@ + $v) { + PermissionLimits::Set(local_channel(), $k, intval($_POST[$k])); + } + + $group_actor = (((x($_POST, 'group_actor')) && (intval($_POST['group_actor']) == 1)) ? 1 : 0); + set_pconfig(local_channel(), 'system', 'group_actor', $group_actor); + + } + + info(t('Privacy settings updated.') . EOL); + Master::Summon(['Directory', local_channel()]); + Libsync::build_sync_packet(); + + goaway(z_root() . '/settings/privacy'); + return; // NOTREACHED + } + + function get() { + + load_pconfig(local_channel()); + + $channel = App::get_channel(); + $global_perms = Permissions::Perms(); + $permiss = []; + + $perm_opts = [ + [t('Only me'), 0], + [t('Only those you specifically allow'), PERMS_SPECIFIC], + [t('Approved connections'), PERMS_CONTACTS], + [t('Any connections'), PERMS_PENDING], + [t('Anybody on this website'), PERMS_SITE], + [t('Anybody in this network'), PERMS_NETWORK], + [t('Anybody authenticated'), PERMS_AUTHED], + [t('Anybody on the internet'), PERMS_PUBLIC] + ]; + + $help = [ + 'view_stream', + 'view_wiki', + 'view_pages', + 'view_storage' + ]; + + $help_txt = t('Advise: set to "Anybody on the internet" and use privacy groups to restrict access'); + $limits = PermissionLimits::Get(local_channel()); + $anon_comments = get_config('system', 'anonymous_comments', true); + + foreach ($global_perms as $k => $perm) { + $options = []; + $can_be_public = (strstr($k, 'view') || ($k === 'post_comments' && $anon_comments)); + + foreach ($perm_opts as $opt) { + if ($opt[1] == PERMS_PUBLIC && (!$can_be_public)) + continue; + + $options[$opt[1]] = $opt[0]; + } + + $permiss[] = [ + $k, + $perm, + $limits[$k], + ((in_array($k, $help)) ? $help_txt : ''), + $options + ]; + } + + //logger('permiss: ' . print_r($permiss,true)); + + $autoperms = get_pconfig(local_channel(), 'system', 'autoperms'); + $index_opt_out = get_pconfig(local_channel(), 'system', 'index_opt_out'); + $group_actor = get_pconfig(local_channel(), 'system', 'group_actor'); + + $permissions_role = get_pconfig(local_channel(), 'system', 'permissions_role', 'custom'); + $permission_limits = ($permissions_role === 'custom'); + + $stpl = get_markup_template('settings_privacy.tpl'); + + $o = replace_macros($stpl, [ + '$ptitle' => t('Privacy Settings'), + '$submit' => t('Submit'), + '$form_security_token' => get_form_security_token("settings"), + '$permission_limits' => $permission_limits, + '$permiss_arr' => $permiss, + '$permission_limits_label' => t('Advanced configuration'), + '$permission_limits_warning' => [ + t('Proceed with caution'), + t('Changing advanced configuration settings can impact your, and your contacts channels functionality and security.'), + t('Accept the risk and continue') + ], + '$autoperms' => ['autoperms', t('Automatically approve new contacts'), $autoperms, '', [t('No'), t('Yes')]], + '$index_opt_out' => ['index_opt_out', t('Opt-out of search engine indexing'), $index_opt_out, '', [t('No'), t('Yes')]], + '$group_actor' => ['group_actor', t('Group actor'), $group_actor, t('Allow this channel to act as a forum'), [t('No'), t('Yes')]], + ]); + + return $o; + } +} diff --git a/Zotlabs/Module/Uexport.php b/Zotlabs/Module/Uexport.php index 8116f616b..870c42802 100644 --- a/Zotlabs/Module/Uexport.php +++ b/Zotlabs/Module/Uexport.php @@ -143,6 +143,10 @@ class Uexport extends Controller { function get() { + if(! local_channel()) { + return; + } + if(! Apps::system_app_installed(local_channel(), 'Channel Export')) { //Do not display any associated widgets at this point App::$pdl = ''; diff --git a/Zotlabs/Update/_1249.php b/Zotlabs/Update/_1249.php new file mode 100644 index 000000000..6d72c4de4 --- /dev/null +++ b/Zotlabs/Update/_1249.php @@ -0,0 +1,31 @@ +' : ''); diff --git a/Zotlabs/Widget/Permcats.php b/Zotlabs/Widget/Permcats.php new file mode 100644 index 000000000..72c80ca0c --- /dev/null +++ b/Zotlabs/Widget/Permcats.php @@ -0,0 +1,79 @@ +listing(); + + $list = 'Roles:
'; + $active = ''; + $active_role = ''; + + if($pcatlist) { + $i = 0; + foreach($pcatlist as $pc) { + if(argc() > 1) { + if($pc['name'] == hex2bin(argv(1))) { + $active = $i; + $active_role = $pc['name']; + } + } + + $list .= '' . $pc['localname'] . '
'; + $i++; + } + } + + if(argc() > 1) { + +/* get role members based on permissions + $test = $pcatlist[$active]['perms']; + + $role_sql = ''; + $count = 0; + foreach ($test as $t) { + $checkinherited = PermissionLimits::Get(local_channel(),$t['name']); + + if($checkinherited & PERMS_SPECIFIC) { + $role_sql .= "( abconfig.k = '" . dbesc($t['name']) . "' AND abconfig.v = '" . intval($t['value']) . "' ) OR "; + $count++; + } + } + + $role_sql = rtrim($role_sql, ' OR '); + + $r = q("SELECT abconfig.xchan, xchan.xchan_name, abook.abook_id FROM abconfig LEFT JOIN xchan on abconfig.xchan = xchan.xchan_hash LEFT JOIN abook ON abconfig.xchan = abook.abook_xchan WHERE xchan.xchan_deleted = 0 and abconfig.chan = %d AND abconfig.cat = 'my_perms' AND ( $role_sql ) GROUP BY abconfig.xchan HAVING count(abconfig.xchan) = %d ORDER BY xchan.xchan_name", + intval(local_channel()), + intval($count) + ); +*/ + + // get role members based on abook_role + + $r = q("SELECT abook.abook_id, abook.abook_role, xchan.xchan_name, xchan.xchan_addr, xchan.xchan_url, xchan.xchan_photo_s FROM abook + LEFT JOIN xchan on abook.abook_xchan = xchan.xchan_hash + WHERE abook.abook_channel = %d AND abook.abook_role = '%s' AND abook_self = 0 AND xchan_deleted = 0 + ORDER BY xchan.xchan_name", + intval(local_channel()), + dbesc($active_role) + ); + + $members = 'Role members:
'; + $members .= '
'; + + foreach ($r as $rr) { + $addr = (($rr['xchan_addr']) ? $rr['xchan_addr'] : $rr['xchan_url']); + $members .= '' . $rr['xchan_name'] . '
' . $addr . '
'; + } + $members .= '
'; + } + return $list . '
' . $members. '
' . $others; + + } +} diff --git a/Zotlabs/Widget/Profile.php b/Zotlabs/Widget/Profile.php index 8bd624c0f..0e5444a56 100644 --- a/Zotlabs/Widget/Profile.php +++ b/Zotlabs/Widget/Profile.php @@ -2,12 +2,16 @@ namespace Zotlabs\Widget; +use App; class Profile { - function widget($args) { + if(!App::$profile['profile_uid']) { + return; + } + $block = observer_prohibited(); - return profile_sidebar(\App::$profile, $block, true, false); - } + return profile_sidebar(App::$profile, $block, true, false); + } } diff --git a/Zotlabs/Widget/Settings_menu.php b/Zotlabs/Widget/Settings_menu.php index 25b80a4b4..4d0f1d2dd 100644 --- a/Zotlabs/Widget/Settings_menu.php +++ b/Zotlabs/Widget/Settings_menu.php @@ -40,6 +40,11 @@ class Settings_menu { 'selected' => ((argv(1) === 'channel') ? 'active' : ''), ), + array( + 'label' => t('Privacy settings'), + 'url' => z_root().'/settings/privacy', + 'selected' => ((argv(1) === 'privacy') ? 'active' : '') + ) ); $tabs[] = array( diff --git a/app/group.apd b/app/group.apd index d026ed23d..bf3ddf4a1 100644 --- a/app/group.apd +++ b/app/group.apd @@ -1,7 +1,7 @@ -version: 3 +version: 4 url: $baseurl/group requires: local_channel name: Privacy Groups -photo: icon:users +photo: icon:lock categories: Networking desc: A tool to create and manage privacy groups. diff --git a/boot.php b/boot.php index 607d64e60..120383d7c 100644 --- a/boot.php +++ b/boot.php @@ -55,10 +55,10 @@ require_once('include/bbcode.php'); require_once('include/items.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '6.5.1' ); +define ( 'STD_VERSION', '6.5.9' ); define ( 'ZOT_REVISION', '6.0' ); -define ( 'DB_UPDATE_VERSION', 1248 ); +define ( 'DB_UPDATE_VERSION', 1249 ); define ( 'PROJECT_BASE', __DIR__ ); @@ -484,7 +484,7 @@ define ( 'NAMESPACE_YMEDIA', 'http://search.yahoo.com/mrss/' ); define ( 'ACTIVITYSTREAMS_JSONLD_REV', 'https://www.w3.org/ns/activitystreams' ); -define ( 'ZOT_APSCHEMA_REV', '/apschema/v1.9' ); +define ( 'ZOT_APSCHEMA_REV', '/apschema/v1.10' ); /** * activity stream defines */ @@ -860,7 +860,7 @@ class App { private static $baseurl; - private static $meta; + public static $meta; /** * App constructor. diff --git a/include/attach.php b/include/attach.php index 067da21ae..2109b84f1 100644 --- a/include/attach.php +++ b/include/attach.php @@ -15,10 +15,10 @@ use Zotlabs\Lib\Libsync; use Zotlabs\Lib\Activity; use Zotlabs\Access\PermissionLimits; use Zotlabs\Daemon\Master; +use Zotlabs\Lib\AccessList; require_once('include/permissions.php'); require_once('include/security.php'); -require_once('include/group.php'); /** * @brief Guess the mimetype from file ending. @@ -2208,7 +2208,7 @@ function attach_recursive_perms($arr_allow_cid, $arr_allow_gid, $arr_deny_cid, $ //lookup all channels in sharee group and add them to sharee $arr_allow_cid if($arr_allow_gid) { - $in_group = expand_groups($arr_allow_gid); + $in_group = AccessList::expand($arr_allow_gid); $arr_allow_cid = array_unique(array_merge($arr_allow_cid, $in_group)); } @@ -2280,7 +2280,7 @@ function attach_recursive_perms($arr_allow_cid, $arr_allow_gid, $arr_deny_cid, $ //check sharee arr_allow_cid against members of allow_gid of all parent folders foreach($parent_arr['allow_gid'] as $folder_arr_allow_gid) { //get the group members - $folder_arr_allow_cid = expand_groups($folder_arr_allow_gid); + $folder_arr_allow_cid = AccessList::expand($folder_arr_allow_gid); foreach($folder_arr_allow_cid as $ac_hash) { $count_values[$ac_hash]++; } diff --git a/include/channel.php b/include/channel.php index 102a03489..00d973738 100644 --- a/include/channel.php +++ b/include/channel.php @@ -15,6 +15,7 @@ use Zotlabs\Render\Comanche; use Zotlabs\Lib\Libzot; use Zotlabs\Lib\Connect; use Zotlabs\Lib\Libsync; +use Zotlabs\Lib\AccessList; require_once('include/crypto.php'); require_once('include/menu.php'); @@ -240,7 +241,7 @@ function create_identity($arr) { // Force a few things on the short term until we can provide a theme or app with choice - $publish = 1; + $publish = 0; if(array_key_exists('publish', $arr)) $publish = intval($arr['publish']); @@ -325,6 +326,12 @@ function create_identity($arr) { if($role_permissions && array_key_exists('perms_auto',$role_permissions)) set_pconfig($r[0]['channel_id'],'system','autoperms',intval($role_permissions['perms_auto'])); + $group_actor = false; + if($role_permissions && array_key_exists('channel_type', $role_permissions) && $role_permissions['channel_type'] === 'group') { + set_pconfig($r[0]['channel_id'], 'system', 'group_actor', 1); + $group_actor = true; + } + $ret['channel'] = $r[0]; if(intval($arr['account_id'])) @@ -374,7 +381,8 @@ function create_identity($arr) { 'xchan_network' => 'zot6', 'xchan_photo_date' => datetime_convert(), 'xchan_name_date' => datetime_convert(), - 'xchan_system' => $system + 'xchan_system' => $system, + 'xchan_pubforum' => $group_actor ] ); if(! $r) @@ -399,14 +407,6 @@ function create_identity($arr) { ] ); - if($role_permissions) { - $myperms = ((array_key_exists('perms_connect',$role_permissions)) ? $role_permissions['perms_connect'] : array()); - } - else { - $x = PermissionRoles::role_perms('social'); - $myperms = $x['perms_connect']; - } - $r = abook_store_lowlevel( [ 'abook_account' => intval($ret['channel']['channel_account_id']), @@ -419,19 +419,18 @@ function create_identity($arr) { ] ); - $x = Permissions::FilledPerms($myperms); - foreach($x as $k => $v) { - set_abconfig($newuid,$hash,'my_perms',$k,$v); - } - if(intval($ret['channel']['channel_account_id'])) { - // Save our permissions role so we can perhaps call it up and modify it later. + + // Set the default permcat + set_pconfig($newuid,'system','default_permcat','default'); if($role_permissions) { + // Save our permissions role so we can perhaps call it up and modify it later. set_pconfig($newuid,'system','permissions_role',$arr['permissions_role']); + if(array_key_exists('online',$role_permissions)) - set_pconfig($newuid,'system','hide_presence',1-intval($role_permissions['online'])); + set_pconfig($newuid,'system','show_online_status', intval($role_permissions['online'])); if(array_key_exists('perms_auto',$role_permissions)) { $autoperms = intval($role_permissions['perms_auto']); set_pconfig($newuid,'system','autoperms',$autoperms); @@ -453,11 +452,10 @@ function create_identity($arr) { // Create a group with yourself as a member. This allows somebody to use it // right away as a default group for new contacts. - require_once('include/group.php'); - $group_hash = group_add($newuid, t('Friends')); + $group_hash = AccessList::add($newuid, t('Friends')); if($group_hash) { - group_add_member($newuid,t('Friends'),$ret['channel']['channel_hash']); + AccessList::member_add($newuid,t('Friends'),$ret['channel']['channel_hash']); $default_collection_str = ''; // if our role_permissions indicate that we're using a default collection ACL, add it. @@ -496,8 +494,7 @@ function create_identity($arr) { if($acct) { $f = connect_and_sync($ret['channel'], $acct); if($f['success']) { - $can_view_stream = their_perms_contains($ret['channel']['channel_id'],$f['abook']['abook_xchan'],'view_stream'); - + $can_view_stream = intval(get_abconfig($ret['channel']['channel_id'], $f['abook']['abook_xchan'], 'their_perms', 'view_stream')); // If we can view their stream, pull in some posts if(($can_view_stream) || ($f['abook']['xchan_network'] === 'rss')) { Master::Summon([ 'Onepoll',$f['abook']['abook_id'] ]); @@ -1488,6 +1485,7 @@ function profile_load($nickname, $profile = '') { if($can_view_profile) { $online = get_online_status($nickname); + App::$profile['online_status'] = $online['result']; } @@ -2060,11 +2058,12 @@ function get_online_status($nick) { return $ret; $r = q("select channel_id, channel_hash from channel where channel_address = '%s' limit 1", - dbesc(argv(1)) + dbesc($nick) ); + if($r) { - $hide = get_pconfig($r[0]['channel_id'],'system','hide_online_status'); - if($hide) + $show = get_pconfig($r[0]['channel_id'],'system','show_online_status'); + if(!$show) return $ret; $x = q("select cp_status from chatpresence where cp_xchan = '%s' and cp_room = 0 limit 1", diff --git a/include/connections.php b/include/connections.php index 0611377ab..11264e6d8 100644 --- a/include/connections.php +++ b/include/connections.php @@ -27,7 +27,8 @@ function abook_store_lowlevel($arr) { 'abook_profile' => ((array_key_exists('abook_profile',$arr)) ? $arr['abook_profile'] : ''), 'abook_incl' => ((array_key_exists('abook_incl',$arr)) ? $arr['abook_incl'] : ''), 'abook_excl' => ((array_key_exists('abook_excl',$arr)) ? $arr['abook_excl'] : ''), - 'abook_instance' => ((array_key_exists('abook_instance',$arr)) ? $arr['abook_instance'] : '') + 'abook_instance' => ((array_key_exists('abook_instance',$arr)) ? $arr['abook_instance'] : ''), + 'abook_role' => ((array_key_exists('abook_role',$arr)) ? $arr['abook_role'] : '') ]; return create_table_from_array('abook',$store); diff --git a/include/conversation.php b/include/conversation.php index a7dfa6b73..d12151fcc 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1070,7 +1070,7 @@ function thread_author_menu($item, $mode = '') { if($contact) { $poke_link = ((Apps::system_app_installed($local_channel, 'Poke')) ? z_root() . '/poke/?f=&c=' . $contact['abook_id'] : ''); if (! intval($contact['abook_self'])) - $contact_url = z_root() . '/connedit/' . $contact['abook_id']; + $contact_url = z_root() . '/connections#' . $contact['abook_id']; $posts_link = z_root() . '/network/?cid=' . $contact['abook_id']; $clean_url = normalise_link($item['author-link']); @@ -1086,7 +1086,9 @@ function thread_author_menu($item, $mode = '') { 'title' => t('View Profile'), 'icon' => 'fw', 'action' => '', - 'href' => $profile_link + 'href' => $profile_link, + 'data' => '', + 'class' => '' ]; } @@ -1096,7 +1098,9 @@ function thread_author_menu($item, $mode = '') { 'title' => t('Recent Activity'), 'icon' => 'fw', 'action' => '', - 'href' => $posts_link + 'href' => $posts_link, + 'data' => '', + 'class' => '' ]; } @@ -1107,6 +1111,8 @@ function thread_author_menu($item, $mode = '') { 'icon' => 'fw', 'action' => 'doFollowAuthor(\'' . $follow_url . '\'); return false;', 'href' => '#', + 'data' => '', + 'class' => '' ]; } @@ -1116,7 +1122,9 @@ function thread_author_menu($item, $mode = '') { 'title' => t('Edit Connection'), 'icon' => 'fw', 'action' => '', - 'href' => $contact_url + 'href' => $contact_url, + 'data' => 'data-id="' . $contact['abook_id'] . '"', + 'class' => 'contact-edit' ]; } @@ -1126,7 +1134,9 @@ function thread_author_menu($item, $mode = '') { 'title' => t('Message'), 'icon' => 'fw', 'action' => '', - 'href' => $pm_url + 'href' => $pm_url, + 'data' => '', + 'class' => '' ]; } @@ -1136,7 +1146,9 @@ function thread_author_menu($item, $mode = '') { 'title' => t('Ratings'), 'icon' => 'fw', 'action' => '', - 'href' => $ratings_url + 'href' => $ratings_url, + 'data' => '', + 'class' => '' ]; } @@ -1146,7 +1158,9 @@ function thread_author_menu($item, $mode = '') { 'title' => t('Poke'), 'icon' => 'fw', 'action' => '', - 'href' => $poke_link + 'href' => $poke_link, + 'data' => '', + 'class' => '' ]; } diff --git a/include/group.php b/include/group.php index bb1ed5ed8..4e1472900 100644 --- a/include/group.php +++ b/include/group.php @@ -326,7 +326,7 @@ function group_side($every="connections",$each="group",$edit = false, $group_id $o = replace_macros($tpl, array( '$title' => t('Privacy Groups'), '$edittext' => t('Edit group'), - '$createtext' => t('Add privacy group'), + '$createtext' => ((argv(1) == 'new' ) ? '' : t('Manage privacy groups')), '$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''), '$groups' => $groups, '$add' => t('add'), diff --git a/include/items.php b/include/items.php index 2ee870c2f..a66703e6e 100644 --- a/include/items.php +++ b/include/items.php @@ -13,9 +13,10 @@ use Zotlabs\Lib\IConfig; use Zotlabs\Lib\Activity; use Zotlabs\Lib\Libsync; use Zotlabs\Lib\Libzot; +use Zotlabs\Lib\ActivityStreams; use Zotlabs\Access\PermissionLimits; use Zotlabs\Access\PermissionRoles; -use Zotlabs\Access\AccessList; +use Zotlabs\Lib\AccessList; use Zotlabs\Daemon\Master; require_once('include/bbcode.php'); @@ -35,8 +36,6 @@ require_once('include/permissions.php'); */ function collect_recipients($item, &$private_envelope,$include_groups = true) { - require_once('include/group.php'); - $private_envelope = ((intval($item['item_private'])) ? true : false); $recipients = array(); @@ -47,7 +46,7 @@ function collect_recipients($item, &$private_envelope,$include_groups = true) { $allow_people = expand_acl($item['allow_cid']); if($include_groups) { - $allow_groups = expand_groups(expand_acl($item['allow_gid'])); + $allow_groups = AccessList::expand(expand_acl($item['allow_gid'])); } else { $allow_groups = []; @@ -72,7 +71,7 @@ function collect_recipients($item, &$private_envelope,$include_groups = true) { } $deny_people = expand_acl($item['deny_cid']); - $deny_groups = expand_groups(expand_acl($item['deny_gid'])); + $deny_groups = AccessList::expand(expand_acl($item['deny_gid'])); $deny = array_unique(array_merge($deny_people,$deny_groups)); @@ -344,6 +343,7 @@ function can_comment_on_post($observer_xchan, $item) { return true; break; case 'any connections': + case 'specific': case 'contacts': case '': if(local_channel() && get_abconfig(local_channel(),$item['owner_xchan'],'their_perms','post_comments')) { @@ -1226,6 +1226,9 @@ function map_scope($scope, $strip = false) { return 'site: ' . App::get_hostname(); case PERMS_PENDING: return 'any connections'; +// uncomment after Hubzilla version 7.0 is running on the majority of active hubs +// case PERMS_SPECIFIC: +// return 'specific'; case PERMS_CONTACTS: default: return 'contacts'; @@ -2537,12 +2540,7 @@ function get_item_contact($item,$contacts) { */ function tag_deliver($uid, $item_id) { - $role = get_pconfig($uid,'system','permissions_role'); - $rolesettings = PermissionRoles::role_perms($role); - $channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal'; - - $is_group = (($channel_type === 'group') ? true : false); - + $is_group = get_pconfig($uid, 'system', 'group_actor'); $mention = false; /* @@ -2579,15 +2577,18 @@ function tag_deliver($uid, $item_id) { } if ($is_group && intval($item['item_private']) === 2 && intval($item['item_thread_top'])) { - // do not turn the groups own direkt messages into group items if($item['item_wall'] && $item['author_xchan'] === $u[0]['channel_hash']) return; // group delivery via DM - if(perm_is_allowed($uid,$item['owner_xchan'],'post_wall') || perm_is_allowed($uid,$item['owner_xchan'],'tag_deliver')) { + if(perm_is_allowed($uid,$item['owner_xchan'],'post_wall')) { logger('group DM delivery for ' . $u[0]['channel_address']); start_delivery_chain($u[0], $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); + q("update item set item_blocked = %d where id = %d", + intval(ITEM_HIDDEN), + intval($item_id) + ); } return; } @@ -2600,13 +2601,6 @@ function tag_deliver($uid, $item_id) { return; } - /* this should not be required anymore due to the check above - if (strpos($item['body'],'[/share]')) { - logger('W2W post already shared'); - return; - } - */ - // group delivery via W2W logger('rewriting W2W post for ' . $u[0]['channel_address']); start_delivery_chain($u[0], $item, $item_id, 0, true, (($item['edited'] != $item['created']) || $item['item_deleted'])); @@ -2677,9 +2671,37 @@ function tag_deliver($uid, $item_id) { intval($uid) ); - if(($x) && intval($x[0]['item_uplink'])) { - start_delivery_chain($u[0],$item,$item_id,$x[0]); + if ($x) { + + // group comments don't normally require a second delivery chain + // but we create a linked Announce so they will show up in the home timeline + // on microblog platforms and this creates a second delivery chain + + if ($is_group && intval($x[0]['item_wall'])) { + // don't let the forked delivery chain recurse + if ($item['verb'] === 'Announce' && $item['author_xchan'] === $u['channel_hash']) { + return; + } + // don't announce moderated content until it has been approved + if (intval($item['item_blocked']) === ITEM_MODERATED) { + return; + } + + // don't boost likes and other response activities as it is likely that + // few platforms will handle this in an elegant way + + if (ActivityStreams::is_response_activity($item['verb'])) { + return; + } + logger('group_comment'); + start_delivery_chain($u[0], $item, $item_id, $x[0], true, (($item['edited'] != $item['created']) || $item['item_deleted'])); + + } + elseif (intval($x[0]['item_uplink'])) { + start_delivery_chain($u,$item,$item_id,$x[0]); + } } + } @@ -2920,13 +2942,7 @@ function item_community_tag($channel,$item) { */ function tgroup_check($uid, $item) { - - $role = get_pconfig($uid,'system','permissions_role'); - $rolesettings = PermissionRoles::role_perms($role); - $channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal'; - - $is_group = (($channel_type === 'group') ? true : false); - + $is_group = get_pconfig($uid, 'system', 'group_actor'); $mention = false; // check that the message originated elsewhere and is a top-level post @@ -3125,6 +3141,10 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false $arr = []; + q("update item set item_hidden = 1 where id = %d", + intval($item_id) + ); + if ($edit) { // process edit or delete action @@ -3155,7 +3175,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false } else { $arr['uuid'] = item_message_id(); - $arr['mid'] = z_root() . '/activity/' . $arr['uuid']; + $arr['mid'] = z_root() . '/item/' . $arr['uuid']; $arr['parent_mid'] = $arr['mid']; } @@ -3173,6 +3193,10 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false $arr['item_private'] = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); + if ($channel['channel_allow_cid'] && empty($channel['channel_allow_gid'])) { + $arr['item_private'] = 2; + } + $arr['item_origin'] = 1; $arr['item_wall'] = 1; $arr['item_thread_top'] = 1; @@ -3192,6 +3216,29 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false $bb .= "[/share]"; $arr['body'] = $bb; + // Conversational objects shouldn't be copied, but other objects should. + if (in_array($item['obj_type'], [ 'Image', 'Event', 'Question' ])) { + $arr['obj'] = $item['obj']; + $t = json_decode($arr['obj'],true); + + if ($t !== NULL) { + $arr['obj'] = $t; + } + $arr['obj']['content'] = bbcode($bb); + $arr['obj']['source']['content'] = $bb; + $arr['obj']['id'] = $arr['mid']; + + if (! array_path_exists('obj/source/mediaType',$arr)) { + $arr['obj']['source']['mediaType'] = 'text/bbcode'; + } + + $arr['obj']['directMessage'] = (intval($arr['item_private']) === 2); + + } + + $arr['tgt_type'] = $item['tgt_type']; + $arr['target'] = $item['target']; + $arr['term'] = $item['term']; $arr['author_xchan'] = $channel['channel_hash']; @@ -3222,6 +3269,92 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false } + if ($group && $parent) { + logger('comment arrived in group', LOGGER_DEBUG); + $arr = []; + + // don't let this recurse. We checked for this before calling, but this ensures + // it doesn't sneak through another way because recursion is nasty. + + if ($item['verb'] === 'Announce' && $item['author_xchan'] === $channel['channel_hash']) { + return; + } + + // Don't send Announce activities for poll responses. + + if ($item['obj_type'] === 'Answer') { + return; + } + + if ($edit) { + if (intval($item['item_deleted'])) { + drop_item($item['id'],false,DROPITEM_PHASE1); + Master::Summon([ 'Notifier','drop',$item['id'] ]); + return; + } + return; + } + else { + $arr['uuid'] = item_message_id(); + $arr['mid'] = z_root() . '/activity/' . $arr['uuid']; + $arr['parent_mid'] = $item['parent_mid']; + //IConfig::Set($arr,'activitypub','context', str_replace('/item/','/conversation/',$item['parent_mid'])); + } + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; + + $arr['verb'] = 'Announce'; + + if (is_array($item['obj'])) { + $arr['obj'] = $item['obj']; + } + elseif (is_string($item['obj']) && strlen($item['obj'])) { + $arr['obj'] = json_decode($item['obj'],true); + } + + if (! $arr['obj']) { + $arr['obj'] = $item['mid']; + } + + if (is_array($arr['obj'])) { + $obj_actor = ((isset($arr['obj']['actor'])) ? ((is_array($arr['obj']['actor'])) ? $arr['obj']['actor']['id'] : $arr['obj']['actor']) : $arr['obj']['attributedTo']); + $mention = Activity::get_actor_bbmention($obj_actor); + $arr['body'] = sprintf( t('🔁 Repeated %1$s\'s %2$s'), $mention, $arr['obj']['type']); + } + + $arr['author_xchan'] = $channel['channel_hash']; + + $arr['item_wall'] = 1; + + $arr['item_private'] = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); + + $arr['item_origin'] = 1; + $arr['item_notshown'] = 1; + + $arr['item_thread_top'] = 0; + + $arr['allow_cid'] = $channel['channel_allow_cid']; + $arr['allow_gid'] = $channel['channel_allow_gid']; + $arr['deny_cid'] = $channel['channel_deny_cid']; + $arr['deny_gid'] = $channel['channel_deny_gid']; + $arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments')); + + $post = item_store($arr); + $post_id = $post['item_id']; + + if ($post_id) { + Master::Summon([ 'Notifier','tgroup',$post_id ]); + } + + q("update channel set channel_lastpost = '%s' where channel_id = %d", + dbesc(datetime_convert()), + intval($channel['channel_id']) + ); + + return; + } + + // Change this copy of the post to a forum head message and deliver to all the tgroup members // also reset all the privacy bits to the forum default permissions @@ -3510,12 +3643,11 @@ function compare_permissions($obj1,$obj2) { * @return array */ function enumerate_permissions($obj) { - require_once('include/group.php'); $allow_people = expand_acl($obj['allow_cid']); - $allow_groups = expand_groups(expand_acl($obj['allow_gid'])); + $allow_groups = AccessList::expand(expand_acl($obj['allow_gid'])); $deny_people = expand_acl($obj['deny_cid']); - $deny_groups = expand_groups(expand_acl($obj['deny_gid'])); + $deny_groups = AccessList::expand(expand_acl($obj['deny_gid'])); $recipients = array_unique(array_merge($allow_people,$allow_groups)); $deny = array_unique(array_merge($deny_people,$deny_groups)); $recipients = array_diff($recipients,$deny); @@ -4252,7 +4384,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C $contact_str = ''; - $contacts = group_get_members($r[0]['id']); + $contacts = AccessList::members($uid, $r[0]['id']); if ($contacts) { foreach($contacts as $c) { if($contact_str) @@ -4268,7 +4400,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str)) or allow_gid like '" . protect_sprintf('%<' . dbesc($r[0]['hash']) . '>%') . "' ) and id = parent $item_normal ) "; - $x = group_rec_byhash($uid,$r[0]['hash']); + $x = AccessList::by_hash($uid, $r[0]['hash']); $result['headline'] = sprintf( t('Privacy group: %s'),$x['gname']); } elseif($arr['cid'] && $uid) { diff --git a/include/nav.php b/include/nav.php index 7cc64ab1b..9278c1587 100644 --- a/include/nav.php +++ b/include/nav.php @@ -26,7 +26,7 @@ function nav($template = 'default') { intval($channel['channel_id']) ); - if (empty($_SESSION['delegate'])) { + if (empty($_SESSION['delegate']) && feature_enabled(local_channel(), 'nav_channel_select')) { $chans = q("select channel_name, channel_id from channel where channel_account_id = %d and channel_removed = 0 order by channel_name ", intval(get_account_id()) ); @@ -97,13 +97,11 @@ function nav($template = 'default') { if (empty($_SESSION['delegate'])) { $nav['manage'] = ['manage', t('Channels'), "", t('Manage your channels'), 'manage_nav_btn']; } - if (Apps::system_app_installed(local_channel(), 'Privacy Groups')) - $nav['group'] = ['group', t('Privacy Groups'), "", t('Manage your privacy groups'), 'group_nav_btn']; $nav['settings'] = ['settings', t('Settings'), "", t('Account/Channel Settings'), 'settings_nav_btn']; - if ($chans && count($chans) > 1 && feature_enabled(local_channel(), 'nav_channel_select')) + if ($chans && count($chans) > 1) $nav['channels'] = $chans; $nav['logout'] = ['logout', t('Logout'), "", t('End this session'), 'logout_nav_btn']; diff --git a/include/permissions.php b/include/permissions.php index d94b70da6..bbd13ed58 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -21,7 +21,7 @@ require_once('include/security.php'); * @param bool $default_ignored (default true) * if false, lie and pretend the ignored person has permissions you are ignoring (used in channel discovery) * - * @returns array of all permissions, key is permission name, value is true or false + * @returns array of all permissions, key is permission name, value is 1 or 0 */ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ignored = true) { @@ -61,7 +61,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ // The uid provided doesn't exist. This would be a big fail. if(! $r) { - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } @@ -70,7 +70,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ if($observer_xchan) { if($channel_perm & PERMS_AUTHED) { - $ret[$perm_name] = true; + $ret[$perm_name] = 1; continue; } @@ -104,7 +104,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ // If they're blocked - they can't read or write if(($x) && intval($x[0]['abook_blocked'])) { - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } @@ -115,7 +115,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ if(($x) && ($default_ignored) && in_array($perm_name,$blocked_anon_perms) && intval($x[0]['abook_ignored'])) { - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } } @@ -123,7 +123,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ // system is blocked to anybody who is not authenticated if(($check_siteblock) && (! $observer_xchan) && intval(get_config('system', 'block_public'))) { - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } @@ -133,16 +133,16 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ if(($observer_xchan) && ($r[0]['channel_hash'] === $observer_xchan)) { if($r[0]['channel_moved'] && (in_array($perm_name,$blocked_anon_perms))) - $ret[$perm_name] = false; + $ret[$perm_name] = 0; else - $ret[$perm_name] = true; + $ret[$perm_name] = 1; continue; } // Anybody at all (that wasn't blocked or ignored). They have permission. if($channel_perm & PERMS_PUBLIC) { - $ret[$perm_name] = true; + $ret[$perm_name] = 1; continue; } @@ -150,7 +150,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ // out, permission is denied. if(! $observer_xchan) { - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } @@ -158,7 +158,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ if($channel_perm & PERMS_NETWORK) { if($x && $x[0]['xchan_network'] === 'zot6') { - $ret[$perm_name] = true; + $ret[$perm_name] = 1; continue; } } @@ -175,9 +175,9 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ } if($c) - $ret[$perm_name] = true; + $ret[$perm_name] = 1; else - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } @@ -186,19 +186,19 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ // handle whether we're allowing any, approved or specific ones if(! $x) { - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } // They are in your address book, but haven't been approved if($channel_perm & PERMS_PENDING && (! intval($x[0]['abook_pseudo']))) { - $ret[$perm_name] = true; + $ret[$perm_name] = 1; continue; } if(intval($x[0]['abook_pending'])) { - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } @@ -207,11 +207,11 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ if($channel_perm & PERMS_CONTACTS) { // it was a fake abook entry, not really a connection if(array_key_exists('abook_pseudo',$x[0]) && intval($x[0]['abook_pseudo'])) { - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } - $ret[$perm_name] = true; + $ret[$perm_name] = 1; continue; } @@ -221,7 +221,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ if($abperms) { foreach($abperms as $ab) { if(($ab['cat'] == 'my_perms') && ($ab['k'] == $perm_name)) { - $ret[$perm_name] = (intval($ab['v']) ? true : false); + $ret[$perm_name] = (intval($ab['v']) ? 1 : 0); break; } } @@ -231,7 +231,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ // No permissions allowed. - $ret[$perm_name] = false; + $ret[$perm_name] = 0; continue; } diff --git a/include/selectors.php b/include/selectors.php index 71e2a387d..d58ef1085 100644 --- a/include/selectors.php +++ b/include/selectors.php @@ -15,7 +15,7 @@ function contact_profile_assign($current) { $select = [ 'profile_assign', - t('Profile to assign new connections'), + t('Select a profile to assign to this contact'), $current, '', $options @@ -70,7 +70,7 @@ function gender_selector($current="",$suffix="") { } $o .= ''; return $o; -} +} function gender_selector_min($current="",$suffix="") { $o = ''; @@ -87,7 +87,7 @@ function gender_selector_min($current="",$suffix="") { } $o .= ''; return $o; -} +} @@ -107,7 +107,7 @@ function sexpref_selector($current="",$suffix="") { } $o .= ''; return $o; -} +} function sexpref_selector_min($current="",$suffix="") { @@ -125,7 +125,7 @@ function sexpref_selector_min($current="",$suffix="") { } $o .= ''; return $o; -} +} @@ -144,7 +144,7 @@ function marital_selector($current="",$suffix="") { } $o .= ''; return $o; -} +} function marital_selector_min($current="",$suffix="") { $o = ''; @@ -161,5 +161,5 @@ function marital_selector_min($current="",$suffix="") { } $o .= ''; return $o; -} +} diff --git a/include/text.php b/include/text.php index d46c089b5..b2b3fce6e 100644 --- a/include/text.php +++ b/include/text.php @@ -12,6 +12,7 @@ use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Zotlabs\Lib\Crypto; use Zotlabs\Lib\SvgSanitizer; use Zotlabs\Lib\Libzot; +use Zotlabs\Lib\AccessList; require_once("include/bbcode.php"); @@ -1753,6 +1754,7 @@ function prepare_body(&$item,$attach = false,$opts = false) { } } + $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ ACTIVITY_POST, ACTIVITY_UPDATE, ACTIVITY_SHARE ])) ? format_poll($item, $s, $opts) : false); if ($poll) { $s = $poll; @@ -1854,11 +1856,16 @@ function format_poll($item,$s,$opts) { return EMPTY_STR; } - $commentable = can_comment_on_post(((local_channel()) ? get_observer_hash() : EMPTY_STR),$item); + $commentable = can_comment_on_post(((local_channel()) ? get_observer_hash() : EMPTY_STR), $item); + + $activated = ((local_channel() && local_channel() == $item['uid'] && get_observer_hash() !== $item['owner_xchan']) ? true : false); + $output = $s; + + if (strpos($item['body'], '[/share]') !== false) { + $output = substr($output, 0, -12); + } - //logger('format_poll: ' . print_r($item,true)); - $activated = ((local_channel() && local_channel() == $item['uid']) ? true : false); - $output = $s . EOL. EOL; + $output .= EOL . EOL; if ($act['type'] === 'Question') { if ($activated and $commentable) { @@ -1884,6 +1891,12 @@ function format_poll($item,$s,$opts) { } } if (array_key_exists('oneOf',$act) && is_array($act['oneOf'])) { + $totalResponses = 0; + foreach ($act['oneOf'] as $poll) { + if (array_path_exists('replies/totalItems',$poll)) { + $totalResponses += intval($poll['replies']['totalItems']); + } + } foreach ($act['oneOf'] as $poll) { if (array_key_exists('name',$poll) && $poll['name']) { $text = html2plain(purify_html($poll['name']),256); @@ -1894,29 +1907,48 @@ function format_poll($item,$s,$opts) { $total = 0; } if ($activated && $commentable) { - $output .= ' ' . $text . '' . ' (' . $total . ')' . EOL; + $output .= '  ' . $text . '' . EOL; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
' . sprintf(tt('%d Vote', '%d Votes', $total, 'noun'), $total) . ' | ' . (($totalResponses) ? intval($total / $totalResponses * 100) . '%' : '0%') . '
'; + $output .= EOL; } + else { - $output .= '( ) ' . $text . ' (' . $total . ')' . EOL; + $output .= '  ' . $text . '' . EOL; + $output .= '
'; + $output .= '
'; + $output .= '
'; + $output .= '
' . sprintf(tt('%d Vote', '%d Votes', $total, 'noun'), $total) . ' | ' . (($totalResponses) ? intval($total / $totalResponses * 100) . '%' : '0%') . '
'; + $output .= EOL; } } } } + + $message = (($totalResponses) ? sprintf(tt('%d Vote in total', '%d Votes in total', $totalResponses, 'noun'), $totalResponses) . EOL : ''); + if ($item['comments_closed'] > NULL_DATE) { $t = datetime_convert('UTC',date_default_timezone_get(), $item['comments_closed'], 'Y-m-d H:i'); $closed = ((datetime_convert() > $item['comments_closed']) ? true : false); if ($closed) { - $message = t('Poll has ended.'); + $message .= t('Poll has ended'); } else { - $message = sprintf(t('Poll ends: %s'),$t); + $message .= sprintf(t('Poll ends in %s'), ''); } - $output .= EOL . '
' . $message . '
'; } - if ($activated and $commentable) { - $output .= EOL . ''. ''; + + $output .= '
' . $message . '
'; + + if ($activated && $commentable && !$closed) { + $output .= ''. ''; } + if (strpos($item['body'], '[/share]') !== false) { + $output .= ''; + } } return $output; } @@ -2989,7 +3021,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true) // weird - as all the other tags are linked to something. if(local_channel() && local_channel() == $profile_uid) { - $grp = group_byname($profile_uid,$name); + $grp = AccessList::byname($profile_uid,$name); if($grp) { $g = q("select hash from pgrp where id = %d and visible = 1 limit 1", @@ -3692,6 +3724,13 @@ function get_forum_channels($uid) { if(! $uid) return; + $r = q("select abook_id, xchan_pubforum, xchan_hash, xchan_network, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 and abook_self = 0 and xchan_pubforum = 1 order by xchan_name", + intval($uid) + ); + + +/* + if(isset(App::$data['forum_channels'])) return App::$data['forum_channels']; @@ -3763,6 +3802,7 @@ function get_forum_channels($uid) { } App::$data['forum_channels'] = $r; +*/ return $r; diff --git a/tests/unit/Access/PermissionLimitsTest.php b/tests/unit/Access/PermissionLimitsTest.php index 57ad42a19..0a90d11df 100644 --- a/tests/unit/Access/PermissionLimitsTest.php +++ b/tests/unit/Access/PermissionLimitsTest.php @@ -45,8 +45,8 @@ class PermissionLimitsTest extends UnitTestCase { * @uses ::call_hooks */ public function testStd_Limits() { - // There are 18 default perms - $permsCount = 18; + // There are 17 default perms + $permsCount = 17; // Create a stub for global function t() with expectation $t = $this->getFunctionMock('Zotlabs\Access', 't'); @@ -69,10 +69,9 @@ class PermissionLimitsTest extends UnitTestCase { $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_comments']); $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_mail']); $this->assertEquals(PERMS_SPECIFIC, $stdlimits['post_like']); - $this->assertEquals(PERMS_SPECIFIC, $stdlimits['tag_deliver']); $this->assertEquals(PERMS_SPECIFIC, $stdlimits['chat']); $this->assertEquals(PERMS_SPECIFIC, $stdlimits['republish']); $this->assertEquals(PERMS_SPECIFIC, $stdlimits['delegate']); } -} \ No newline at end of file +} diff --git a/tests/unit/Access/PermissionRolesTest.php b/tests/unit/Access/PermissionRolesTest.php index dd55eb6e2..3d3cbbae5 100644 --- a/tests/unit/Access/PermissionRolesTest.php +++ b/tests/unit/Access/PermissionRolesTest.php @@ -40,7 +40,7 @@ class PermissionRolesTest extends UnitTestCase { use PHPMock; public function testVersion() { - $expectedVersion = 2; + $expectedVersion = 3; $this->assertEquals($expectedVersion, PermissionRoles::version()); @@ -58,23 +58,12 @@ class PermissionRolesTest extends UnitTestCase { } ); - $roles = PermissionRoles::roles(); + $roles = PermissionRoles::channel_roles(); $r = new PermissionRoles(); - $this->assertEquals($roles, $r->roles()); + $this->assertEquals($roles, $r->channel_roles()); - $socialNetworking = [ - 'social_federation' => 'Social - Federation', - 'social' => 'Social - Mostly Public', - 'social_restricted' => 'Social - Restricted', - 'social_private' => 'Social - Private' - ]; + $this->assertCount(4, $roles, 'There should be 4 channel roles.'); - Assert::assertArraySubset(['Social Networking' => $socialNetworking], $roles); - $this->assertEquals($socialNetworking, $roles['Social Networking']); - - $this->assertCount(5, $roles, 'There should be 5 permission groups.'); - - $this->assertCount(1, $roles['Other'], "In the 'Other' group should be just one permission role"); } @@ -88,12 +77,9 @@ class PermissionRolesTest extends UnitTestCase { $t = $this->getFunctionMock('Zotlabs\Access', 't'); $t = $this->getFunctionMock('Zotlabs\Access', 'get_config'); - $rp_social = PermissionRoles::role_perms('social'); - $this->assertEquals('social', $rp_social['role']); - + $rp_social = PermissionRoles::role_perms('personal'); + $this->assertEquals('personal', $rp_social['role']); - $rp_custom = PermissionRoles::role_perms('custom'); - $this->assertEquals(['role' => 'custom'], $rp_custom); $rp_nonexistent = PermissionRoles::role_perms('nonexistent'); $this->assertEquals(['role' => 'nonexistent'], $rp_nonexistent); diff --git a/tests/unit/Access/PermissionsTest.php b/tests/unit/Access/PermissionsTest.php index 40724fff8..3ab567ad0 100644 --- a/tests/unit/Access/PermissionsTest.php +++ b/tests/unit/Access/PermissionsTest.php @@ -37,7 +37,7 @@ class PermissionsTest extends UnitTestCase { use PHPMock; public function testVersion() { - $expectedVersion = 2; + $expectedVersion = 3; // static call $this->assertEquals($expectedVersion, Permissions::version()); @@ -60,8 +60,8 @@ class PermissionsTest extends UnitTestCase { * @uses ::call_hooks */ public function testPerms() { - // There are 18 default perms - $permsCount = 18; + // There are 17 default perms + $permsCount = 17; // Create a stub for global function t() with expectation $t = $this->getFunctionMock('Zotlabs\Access', 't'); @@ -94,8 +94,8 @@ class PermissionsTest extends UnitTestCase { * @uses ::call_hooks */ public function testPermsFilter() { - // There are 18 default perms - $permsCount = 18; + // There are 17 default perms + $permsCount = 17; // Create a stub for global function t() with expectation $t = $this->getFunctionMock('Zotlabs\Access', 't'); @@ -154,7 +154,6 @@ class PermissionsTest extends UnitTestCase { 'post_comments' => 0, 'post_mail' => 0, 'post_like' => 0, - 'tag_deliver' => 0, 'chat' => 0, 'republish' => 0, 'delegate' => 0 @@ -177,7 +176,6 @@ class PermissionsTest extends UnitTestCase { 'post_comments' => 0, 'post_mail' => 0, 'post_like' => 0, - 'tag_deliver' => 0, 'chat' => 0, 'republish' => 0, 'delegate' => 0 @@ -200,7 +198,6 @@ class PermissionsTest extends UnitTestCase { 'post_comments' => 0, 'post_mail' => 0, 'post_like' => 0, - 'tag_deliver' => 0, 'chat' => 0, 'republish' => 0, 'delegate' => 0 @@ -234,7 +231,6 @@ class PermissionsTest extends UnitTestCase { 'post_comments' => 0, 'post_mail' => 0, 'post_like' => 0, - 'tag_deliver' => 0, 'chat' => 0, 'republish' => 0, 'delegate' => 0 diff --git a/view/css/mod_connections.css b/view/css/mod_connections.css index 4c26193b4..6a83367b8 100644 --- a/view/css/mod_connections.css +++ b/view/css/mod_connections.css @@ -1,17 +1,8 @@ +#contacts-follow-form, #contacts-search-form { display: none; } -.section-subtitle-wrapper .btn-xs { - margin-top: -2px; -} - -.contact-search { - height: 22px; - border-top-right-radius: 0px; - border-bottom-right-radius: 0px; -} - .directory-photo-img.archived { opacity: 0.3; filter:alpha(opacity=30); @@ -39,7 +30,8 @@ } .contact-photo-wrapper .oneway-overlay { - margin-top: -25px; - margin-left: 53px; - font-size: 20px; + margin-top: -18px; + margin-left: 62px; + font-size: 1.2rem; + display: inherit; /* this is required for chromium */ } diff --git a/view/css/widgets.css b/view/css/widgets.css index df77940dd..0a091272c 100644 --- a/view/css/widgets.css +++ b/view/css/widgets.css @@ -244,9 +244,8 @@ a.wikilist { /* contact block */ .contact-block-div .oneway-overlay { font-size: .9rem; - margin-left: -1.2rem; - margin-top: 2rem; - opacity: 0.8; + margin-left: -1rem; + margin-top: 1.9rem; } #cid-filter-wrapper { diff --git a/view/js/main.js b/view/js/main.js index 0e16809e4..f4f641e33 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -525,11 +525,14 @@ function showHideComments(id) { } } -function openClose(theID) { - if(document.getElementById(theID).style.display == "block") { +function openClose(theID, display) { + if (typeof display == typeof undefined) + display = 'block'; + + if(document.getElementById(theID).style.display == display) { document.getElementById(theID).style.display = "none"; } else { - document.getElementById(theID).style.display = "block"; + document.getElementById(theID).style.display = display; } } @@ -541,9 +544,11 @@ function openCloseTR(theID) { } } -function closeOpen(theID) { +function closeOpen(theID, display) { + if (typeof display == typeof undefined) + display = 'block'; if(document.getElementById(theID).style.display == "none") { - document.getElementById(theID).style.display = "block"; + document.getElementById(theID).style.display = display; } else { document.getElementById(theID).style.display = "none"; } diff --git a/view/js/mod_connections.js b/view/js/mod_connections.js index db18e078d..848e9ed9f 100644 --- a/view/js/mod_connections.js +++ b/view/js/mod_connections.js @@ -1,5 +1,5 @@ $(document).ready(function() { $("#contacts-search").contact_autocomplete(baseurl + '/acl', 'a', true); $(".autotime").timeago(); -}); +}); diff --git a/view/pdl/mod_chat.pdl b/view/pdl/mod_chat.pdl index 808ba3d5a..8a79b4b12 100644 --- a/view/pdl/mod_chat.pdl +++ b/view/pdl/mod_chat.pdl @@ -1,5 +1,5 @@ [region=aside] -[widget=vcard][/widget] +[widget=profile][/widget] [widget=chatroom_list][/widget] [widget=bookmarkedchats][/widget] [widget=suggestedchats][/widget] diff --git a/view/pdl/mod_connections.pdl b/view/pdl/mod_connections.pdl index b777cada5..3c3dfd313 100644 --- a/view/pdl/mod_connections.pdl +++ b/view/pdl/mod_connections.pdl @@ -1,7 +1,4 @@ [region=aside] -[widget=follow][/widget] -[widget=collections][var=mode][connections[/arg][/widget] -[widget=suggestions][/widget] [widget=findpeople][/widget] [/region] [region=right_aside] diff --git a/view/pdl/mod_connedit.pdl b/view/pdl/mod_connedit.pdl index 4bdadb5e8..fa2f2969b 100644 --- a/view/pdl/mod_connedit.pdl +++ b/view/pdl/mod_connedit.pdl @@ -1,8 +1,6 @@ [region=aside] [widget=vcard][/widget] [widget=collections][var=mode]abook[/var][/widget] -[widget=suggestions][/widget] -[widget=findpeople][/widget] [/region] [region=right_aside] [widget=notifications][/widget] diff --git a/view/pdl/mod_import_items.pdl b/view/pdl/mod_import_items.pdl new file mode 100644 index 000000000..e657fa88b --- /dev/null +++ b/view/pdl/mod_import_items.pdl @@ -0,0 +1,3 @@ +[region=right_aside] +[widget=notifications][/widget] +[/region] diff --git a/view/pdl/mod_permcats.pdl b/view/pdl/mod_permcats.pdl new file mode 100644 index 000000000..bc6c89920 --- /dev/null +++ b/view/pdl/mod_permcats.pdl @@ -0,0 +1,7 @@ +[region=aside] +[widget=permcats][/widget] +[/region] +[region=right_aside] +[widget=notifications][/widget] +[widget=newmember][/widget] +[/region] diff --git a/view/pdl/mod_profperm.pdl b/view/pdl/mod_profperm.pdl index 7e15fc869..d7e5d29f3 100644 --- a/view/pdl/mod_profperm.pdl +++ b/view/pdl/mod_profperm.pdl @@ -1,5 +1,5 @@ [region=aside] -[widget=fullprofile][/widget] +[widget=profile][/widget] [/region] [region=right_aside] [widget=notifications][/widget] diff --git a/view/pdl/mod_viewconnections.pdl b/view/pdl/mod_viewconnections.pdl index 7e15fc869..d7e5d29f3 100644 --- a/view/pdl/mod_viewconnections.pdl +++ b/view/pdl/mod_viewconnections.pdl @@ -1,5 +1,5 @@ [region=aside] -[widget=fullprofile][/widget] +[widget=profile][/widget] [/region] [region=right_aside] [widget=notifications][/widget] diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css index ac5b6a80a..542940404 100644 --- a/view/theme/redbasic/css/style.css +++ b/view/theme/redbasic/css/style.css @@ -418,11 +418,6 @@ footer { filter:alpha(opacity=100); } -#profile-photo-wrapper img { - width: 100%; - height: 100%; -} - #hide-friends-yes-label, #hide-friends-no-label { margin-left: 125px; @@ -1223,24 +1218,24 @@ img.mail-conv-sender-photo { } .menu-img-3 { - width: 3.3em; - height: 3.3em; + width: 2.7rem; + height: 2.7rem; margin-right: 5px; border-radius: $radius; float: left; } .menu-img-2 { - height: 2.2em; - width: 2.2em; + height: 1.8rem; + width: 1.8rem; margin-right: 5px; border-radius: $radius; float: left; } .menu-img-1 { - height: 1.28571429em; - width: 1.28571429em; + height: 1.1rem; + width: 1.1rem; border-radius: $radius; } @@ -1784,7 +1779,7 @@ dl.bb-dl > dd > li { .oneway-overlay { position: absolute; - text-shadow: -2px 0 1px #fff, 0 2px 1px#fff, 2px 0 1px #fff, 0 -2px 1px #fff; + text-shadow: -1px 0 1px #fff, 0 1px 1px#fff, 1px 0 1px #fff, 0 -1px 1px #fff; } .cover-photo-review { diff --git a/view/theme/redbasic/schema/Focus-Boxy.css b/view/theme/redbasic/schema/Focus-Boxy.css index b9b259796..90fd51b02 100644 --- a/view/theme/redbasic/schema/Focus-Boxy.css +++ b/view/theme/redbasic/schema/Focus-Boxy.css @@ -3,13 +3,31 @@ } .wall-item-content-wrapper.comment { - border-bottom: 1px solid #dee2e6; + border-bottom: 1px solid rgba(0,0,0,.125); } .widget { - border: 1px solid #dee2e6; + border: 1px solid rgba(0,0,0,.125); } #note-text { border: 1px solid transparent; } + +.vcard-card { + border: 1px solid rgba(0,0,0,.125); + border-bottom: 0; +} + +.vcard-card .card { + border-top: 0; + border-right: 0; + border-left: 0; +} + +.vcard-card .vcard { + border: 1px solid rgba(0,0,0,.125); + border-top: 0; + border-right: 0; + border-left: 0; +} diff --git a/view/tpl/abook_edit.tpl b/view/tpl/abook_edit.tpl index 686b40a54..28631ed68 100644 --- a/view/tpl/abook_edit.tpl +++ b/view/tpl/abook_edit.tpl @@ -24,6 +24,7 @@ {{if $abook_prev || $abook_next}}
+ {{if $sections}}
+ {{/if}}
{{/if}} @@ -40,6 +42,65 @@

{{$header}}

+
+ + + + +
+  {{$permcat_new}} + {{include file="field_select.tpl" field=$permcat}} + + + +
+ {{if $notself}} {{foreach $tools as $tool}} {{if $tool.info}} @@ -73,33 +134,9 @@
{{/if}} - - - - -
{{if $notself}} - {{if $is_pending}} -
- -
-
- {{include file="field_checkbox.tpl" field=$unapproved}} -
- -
-
-
-
- {{/if}} {{if ! $is_pending}}
@@ -438,85 +475,6 @@ {{/if}} - {{if $rating}} -
- -
-
-
- {{$rating_info}} -
-
{{$lbl_rating_label}}
- {{$rating}} - {{include file="field_textarea.tpl" field=$rating_text}} - -
- -
-
-
-
- {{/if}} - - {{/if}} - - {{if ! $is_pending}} -
- {{if $notself}} - - {{/if}} -
-
-
- {{if $notself}}{{$permnote}}{{/if}} - {{if $self}}{{$permnote_self}}{{/if}} -
- - {{if $permcat_enable}} -  {{$permcat_new}} - {{include file="field_select.tpl" field=$permcat}} - {{/if}} - - - - - {{if $notself}} - - {{/if}} - - - {{foreach $perms as $prm}} - {{include file="field_acheckbox.tpl" field=$prm}} - {{/foreach}} -
{{$them}}{{$me}}
- - {{if $self}} -
- - {{include file="field_checkbox.tpl" field=$autoperms}} -
- {{/if}} - -
- -
-
-
-
{{/if}}
diff --git a/view/tpl/admin_site.tpl b/view/tpl/admin_site.tpl index 6882c3b8a..fa942baff 100644 --- a/view/tpl/admin_site.tpl +++ b/view/tpl/admin_site.tpl @@ -31,7 +31,7 @@

{{$registration}}

{{include file="field_input.tpl" field=$register_text}} - {{include file="field_select_grouped.tpl" field=$role}} + {{include file="field_select.tpl" field=$role}} {{include file="field_select.tpl" field=$register_policy}} {{** include file="field_checkbox.tpl" field=$register_wo_email **}} {{include file="register_duty.tpl" field=$register_duty}} diff --git a/view/tpl/connection_template.tpl b/view/tpl/connection_template.tpl index e7ab559cb..5c1542111 100644 --- a/view/tpl/connection_template.tpl +++ b/view/tpl/connection_template.tpl @@ -1,23 +1,12 @@
- {{if $contact.approve && $contact.ignore}} -
- - - {{$contact.ignore}} - - {{/if}} - {{if $contact.connect}} - {{$contact.connect}} - {{/if}} - {{$contact.delete}} - {{$contact.edit}} - {{if $contact.approve}} -
- {{/if}} + {{$contact.role}} +
-

{{if $contact.public_forum}} {{/if}}{{$contact.name}}{{if $contact.phone}} {{/if}}

+

{{if $contact.public_forum}} {{/if}}{{$contact.name}}{{if $contact.phone}} {{/if}}

diff --git a/view/tpl/connections.tpl b/view/tpl/connections.tpl index 1719a6522..5fec38a84 100644 --- a/view/tpl/connections.tpl +++ b/view/tpl/connections.tpl @@ -1,7 +1,10 @@
-
+
- + +
+
+
+
+ {{if $abook_usage_message}} +
+ {{$abook_usage_message}} +
+ {{/if}} +
+
+ +
@@ -34,3 +50,5 @@
+{{include file="contact_edit_modal.tpl"}} + diff --git a/view/tpl/connstatus.tpl b/view/tpl/connstatus.tpl index 869345682..30f450820 100644 --- a/view/tpl/connstatus.tpl +++ b/view/tpl/connstatus.tpl @@ -1 +1 @@ - + diff --git a/view/tpl/contact_edit.tpl b/view/tpl/contact_edit.tpl new file mode 100644 index 000000000..3c4ed2ffe --- /dev/null +++ b/view/tpl/contact_edit.tpl @@ -0,0 +1,133 @@ +
+
+
+ +
+
+ {{include file="field_select.tpl" field=$permcat}} + + +  {{$permcat_new}} + + + + + + + + + + + {{foreach $perms as $perm}} + + + + + + {{/foreach}} + + +
Permission{{$them}}{{$me}}
{{$perm.1}} + {{if $perm.2}} + + {{else}} + + {{/if}} + + {{if $perm.3}} + + {{else}} + + {{/if}} +
+
+
+
+ {{if $groups}} +
+ +
+
+ {{foreach $groups as $group}} + {{include file="field_checkbox.tpl" field=$group}} + {{/foreach}} + +  Privacy groups + +
+
+
+ {{/if}} + {{if $multiprofs}} +
+ +
+
+ {{$profile_select}} + +  Profiles + +
+
+
+ {{/if}} + {{if $slide}} +
+ +
+
+
+ {{$slide}} + +
+
+
+ {{/if}} + {{if $connfilter}} +
+ +
+
+ {{include file="field_textarea.tpl" field=$incl}} + {{include file="field_textarea.tpl" field=$excl}} +
+
+
+ {{else}} + + + {{/if}} +
+
diff --git a/view/tpl/contact_edit_header.tpl b/view/tpl/contact_edit_header.tpl new file mode 100644 index 000000000..997d294bd --- /dev/null +++ b/view/tpl/contact_edit_header.tpl @@ -0,0 +1,9 @@ + +
+
{{if $is_group}} {{/if}}{{$name}}
+
{{$addr}}
+
diff --git a/view/tpl/contact_edit_modal.tpl b/view/tpl/contact_edit_modal.tpl new file mode 100644 index 000000000..be290c403 --- /dev/null +++ b/view/tpl/contact_edit_modal.tpl @@ -0,0 +1,152 @@ + + diff --git a/view/tpl/contact_edit_tools.tpl b/view/tpl/contact_edit_tools.tpl new file mode 100644 index 000000000..565b9df86 --- /dev/null +++ b/view/tpl/contact_edit_tools.tpl @@ -0,0 +1,14 @@ + + diff --git a/view/tpl/conv_frame.tpl b/view/tpl/conv_frame.tpl index c28bb732a..4237c671b 100644 --- a/view/tpl/conv_frame.tpl +++ b/view/tpl/conv_frame.tpl @@ -18,3 +18,4 @@
+{{include file="contact_edit_modal.tpl"}} diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl index 7c3505410..0a07319c8 100644 --- a/view/tpl/conv_item.tpl +++ b/view/tpl/conv_item.tpl @@ -40,7 +40,7 @@ {{/if}} @@ -48,7 +48,7 @@
{{if $item.lock}} {{/if}} diff --git a/view/tpl/conv_list.tpl b/view/tpl/conv_list.tpl index a20a6de8d..b4071ba16 100644 --- a/view/tpl/conv_list.tpl +++ b/view/tpl/conv_list.tpl @@ -43,7 +43,7 @@
{{if $item.lock}} {{/if}} diff --git a/view/tpl/conversation.tpl b/view/tpl/conversation.tpl index 82c7be922..6729cf55c 100644 --- a/view/tpl/conversation.tpl +++ b/view/tpl/conversation.tpl @@ -9,10 +9,10 @@ {{/if}} - + {{include file="{{$item.template}}"}} - - + + {{/foreach}}
{{/foreach}} diff --git a/view/tpl/field_acheckbox.tpl b/view/tpl/field_acheckbox.tpl index 4c8b62f36..44f65fefd 100644 --- a/view/tpl/field_acheckbox.tpl +++ b/view/tpl/field_acheckbox.tpl @@ -1,24 +1,31 @@ - + -
- {{$field.6}} + + {{$field.6}} - {{if $notself}} - - {{if $field.2 == 1}}{{/if}} - {{if $field.2 == 0}}{{/if}} - - {{/if}} - - {{if $self || !$field.5 }} - - {{/if}} - {{if $notself && $field.5}} - - {{if $field.3}}{{else}}{{/if}} + + {{if $field.5}} + + {{$inherited}} + {{if $field.7}} + + {{else}} + + {{/if}} + {{/if}} - {{if $field.5}}{{$inherited}}{{if $self}}{{if $field.7}} {{else}} {{/if}}{{/if}}{{/if}} + {{if $is_system_role}} + {{if $field.3}} + + {{else}} + + {{/if}} + {{else}} + + {{/if}} + + diff --git a/view/tpl/field_checkbox.tpl b/view/tpl/field_checkbox.tpl index a1ab42d5e..670bb7e29 100644 --- a/view/tpl/field_checkbox.tpl +++ b/view/tpl/field_checkbox.tpl @@ -1,6 +1,6 @@
-
+
{{$field.3}}
{{* diff --git a/view/tpl/group_edit.tpl b/view/tpl/group_edit.tpl index 5568179af..61203ab10 100644 --- a/view/tpl/group_edit.tpl +++ b/view/tpl/group_edit.tpl @@ -13,6 +13,8 @@ {{include file="field_input.tpl" field=$gname}} {{include file="field_checkbox.tpl" field=$public}} + {{include file="field_checkbox.tpl" field=$is_default_acl}} + {{include file="field_checkbox.tpl" field=$is_default_group}} {{$pgrp_extras}} {{$delete}} diff --git a/view/tpl/group_selection.tpl b/view/tpl/group_selection.tpl index a91658464..7db80e06f 100644 --- a/view/tpl/group_selection.tpl +++ b/view/tpl/group_selection.tpl @@ -1,8 +1,8 @@
- - + +
diff --git a/view/tpl/group_side.tpl b/view/tpl/group_side.tpl index 14f714ae9..979d20aa5 100644 --- a/view/tpl/group_side.tpl +++ b/view/tpl/group_side.tpl @@ -13,9 +13,11 @@
{{$group.text}} {{/foreach}} + {{if $createtext}} + {{/if}}
diff --git a/view/tpl/micropro_card.tpl b/view/tpl/micropro_card.tpl index 058bfc14c..40a7967c5 100644 --- a/view/tpl/micropro_card.tpl +++ b/view/tpl/micropro_card.tpl @@ -1,5 +1,5 @@ - {{if $perminfo}}{{include "connstatus.tpl"}}{{/if}} + {{if $perminfo}}{{include "connstatus.tpl"}}{{/if}} {{$name}} {{$addr}}
{{$network}}
diff --git a/view/tpl/new_channel.tpl b/view/tpl/new_channel.tpl index 8d72df55b..f11a4291f 100644 --- a/view/tpl/new_channel.tpl +++ b/view/tpl/new_channel.tpl @@ -18,17 +18,17 @@ {{if $default_role}} {{else}} - {{include file="field_select_grouped.tpl" field=$role}} + {{include file="field_select.tpl" field=$role}} {{/if}} - + {{include file="field_input.tpl" field=$name}} - + {{include file="field_input.tpl" field=$nickname}} - - + +
- +
diff --git a/view/tpl/notes.tpl b/view/tpl/notes.tpl index 902691fae..24c3ec53c 100644 --- a/view/tpl/notes.tpl +++ b/view/tpl/notes.tpl @@ -8,7 +8,7 @@ {{else}}
{{$strings.read}}
-

{{$banner}}

+

{{$strings.title}}

{{/if}}
{{$html}}
diff --git a/view/tpl/permcats.tpl b/view/tpl/permcats.tpl index 5b2d811d7..279903048 100644 --- a/view/tpl/permcats.tpl +++ b/view/tpl/permcats.tpl @@ -4,49 +4,37 @@
- -
- - {{include file="field_input.tpl" field=$name}} + + -
- -
-
+ {{if $is_system_role}} + + + {{/if}} -
- -
-
-
- {{$permnote}} -
+ {{include file="field_input.tpl" field=$name}} + {{include file="field_checkbox.tpl" field=$default_role}} - - - - - {{foreach $perms as $prm}} - {{include file="field_acheckbox.tpl" field=$prm}} - {{/foreach}} -
{{$me}}
+ {{$group_select}} -
- -
+
+

+ {{$permlbl}} +

-
- {{if $permcats}} -
+
+ {{$permnote}} +
+ + {{foreach $perms as $prm}} + {{include file="field_acheckbox.tpl" field=$prm}} + {{/foreach}} +
+
+ +
+ {{**if $permcats}} {{foreach $permcats as $k => $v}} @@ -55,10 +43,8 @@ {{/foreach}}
-
- {{/if}} + {{/if**}} +
- -
diff --git a/view/tpl/privacy_groups.tpl b/view/tpl/privacy_groups.tpl index c06f5b0ca..0bbc998a1 100644 --- a/view/tpl/privacy_groups.tpl +++ b/view/tpl/privacy_groups.tpl @@ -8,6 +8,8 @@ {{include file="field_input.tpl" field=$gname}} {{include file="field_checkbox.tpl" field=$public}} + {{include file="field_checkbox.tpl" field=$is_default_acl}} + {{include file="field_checkbox.tpl" field=$is_default_group}} {{$pgrp_extras}} diff --git a/view/tpl/profile_edit.tpl b/view/tpl/profile_edit.tpl index 95346b3a8..3f5814c4a 100644 --- a/view/tpl/profile_edit.tpl +++ b/view/tpl/profile_edit.tpl @@ -50,7 +50,7 @@ @@ -84,7 +84,17 @@ {{$dob}} {{/if}} + {{$profile_in_dir}} + + {{$suggestme}} + + {{if $show_presence}} + {{include file="field_checkbox.tpl" field=$show_presence}} + {{/if}} + + {{if $hide_friends}} {{include file="field_checkbox.tpl" field=$hide_friends}} + {{/if}}
diff --git a/view/tpl/profile_vcard.tpl b/view/tpl/profile_vcard.tpl index 8ebc9a311..9002d3742 100644 --- a/view/tpl/profile_vcard.tpl +++ b/view/tpl/profile_vcard.tpl @@ -1,5 +1,5 @@ -
-
+
+
{{if $editmenu}} @@ -49,10 +49,10 @@ {{if $details}}
{{if $profile.pdesc}} -
{{$profile.pdesc}}
+
{{$profile.pdesc}}
{{/if}} {{if $location}} -
+
{{$location}}
{{if $profile.address}} @@ -72,25 +72,25 @@
{{/if}} {{if $hometown}} -
+
{{$hometown}}
{{$profile.hometown}}
{{/if}} {{if $gender}} -
+
{{$gender}}
{{if $profile.gender_icon}} {{/if}}{{$profile.gender}}
{{/if}} {{if $marital}} -
+
 {{$marital}}
{{$profile.marital}}
{{/if}} {{if $homepage}} -
+
{{$homepage}}
{{$profile.homepage}}
diff --git a/view/tpl/search_item.tpl b/view/tpl/search_item.tpl index ee89973a8..f3d0a8d03 100644 --- a/view/tpl/search_item.tpl +++ b/view/tpl/search_item.tpl @@ -36,7 +36,7 @@
{{if $item.lock}} {{/if}}
diff --git a/view/tpl/settings.tpl b/view/tpl/settings.tpl index 353da9c2b..9b23d7d82 100644 --- a/view/tpl/settings.tpl +++ b/view/tpl/settings.tpl @@ -18,13 +18,14 @@
- {{include file="field_input.tpl" field=$username}} + {{include file="field_select.tpl" field=$role}} {{include file="field_select_grouped.tpl" field=$timezone}} {{include file="field_input.tpl" field=$defloc}} {{include file="field_checkbox.tpl" field=$allowloc}} {{include file="field_checkbox.tpl" field=$adult}} {{include file="field_input.tpl" field=$photo_path}} {{include file="field_input.tpl" field=$attach_path}} + {{include file="field_input.tpl" field=$expire}} {{if $basic_addon}} {{$basic_addon}} {{/if}} @@ -34,66 +35,6 @@
-
- -
-
- {{include file="field_select_grouped.tpl" field=$role}} - {{$autoperms}} -
-
- -
- - -
- -
- {{$group_select}} - {{include file="field_checkbox.tpl" field=$hide_presence}} - {{$profile_in_dir}} -
-
- {{$suggestme}} - {{include file="field_checkbox.tpl" field=$blocktags}} - {{include file="field_input.tpl" field=$expire}} -
- {{if $permcat_enable}} - {{include file="field_select.tpl" field=$defpermcat}} - {{/if}} - - {{if $sec_addon}} - {{$sec_addon}} - {{/if}} -
- -
-
-
-
-
+ @@ -31,20 +31,36 @@ {{include file="field_acheckbox.tpl" field=$prm}} {{/foreach}} -
- +
+ {{if !$is_system_role && $return_path}} + + {{/if}} +
- {{**if $permcats}} - - {{foreach $permcats as $k => $v}} - - - - - {{/foreach}} -
{{$v}}
- {{/if**}} -
+{{if !$is_system_role && $return_path}} + +{{/if}} -- cgit v1.2.3 From 91cea1f28a8734f3fbab38260cc301026df7b56b Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 17 Dec 2021 15:01:25 +0100 Subject: add template --- view/tpl/permcats_widget.tpl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 view/tpl/permcats_widget.tpl diff --git a/view/tpl/permcats_widget.tpl b/view/tpl/permcats_widget.tpl new file mode 100644 index 000000000..a7ebd91ba --- /dev/null +++ b/view/tpl/permcats_widget.tpl @@ -0,0 +1,27 @@ +
+

{{$roles_label}}

+ +
+ +{{if $members}} +
+

{{$members_label}}

+
+ {{foreach $members as $member}} + + + {{$member.name}}
+ {{$member.addr}} +
+ {{/foreach}} +
+
+{{/if}} -- cgit v1.2.3 From 32a9eaf3b6a68626580078a3302f8dd8e85eb165 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 17 Dec 2021 15:30:26 +0100 Subject: update db schemas --- install/schema_mysql.sql | 4 +++- install/schema_postgres.sql | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql index 8267d17f7..054c1da03 100644 --- a/install/schema_mysql.sql +++ b/install/schema_mysql.sql @@ -37,6 +37,7 @@ CREATE TABLE IF NOT EXISTS `abook` ( `abook_incl` text NOT NULL, `abook_excl` text NOT NULL, `abook_instance` text NOT NULL, + `abook_role` char(191) NOT NULL DEFAULT '', PRIMARY KEY (`abook_id`), KEY `abook_account` (`abook_account`), KEY `abook_channel` (`abook_channel`), @@ -58,7 +59,8 @@ CREATE TABLE IF NOT EXISTS `abook` ( KEY `abook_unconnected` (`abook_unconnected`), KEY `abook_self` (`abook_self`), KEY `abook_not_here` (`abook_not_here`), - KEY `abook_feed` (`abook_feed`) + KEY `abook_feed` (`abook_feed`), + KEY `abook_role` (`abook_role`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `account` ( diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql index f3fe28f93..c1cbc832b 100644 --- a/install/schema_postgres.sql +++ b/install/schema_postgres.sql @@ -37,6 +37,7 @@ CREATE TABLE "abook" ( "abook_incl" TEXT NOT NULL DEFAULT '', "abook_excl" TEXT NOT NULL DEFAULT '', "abook_instance" TEXT NOT NULL DEFAULT '', + "abook_role" varchar(64) NOT NULL DEFAULT '', PRIMARY KEY ("abook_id") ); create index "abook_account" on abook ("abook_account"); @@ -61,6 +62,7 @@ CREATE TABLE "abook" ( create index "abook_dob" on abook ("abook_dob"); create index "abook_connected" on abook ("abook_connected"); create index "abook_channel_closeness" on abook ("abook_channel", "abook_closeness"); + create index "abook_role" on abook ("abook_role"); CREATE TABLE "account" ( "account_id" serial NOT NULL, -- cgit v1.2.3 From bfd3da43ac9226e53188a03ff1414a18422e91b4 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 17 Dec 2021 19:48:09 +0100 Subject: access token refactor --- Zotlabs/Module/Tokens.php | 194 +++++++++++++++++++++++++++++++++++--------- boot.php | 2 +- include/channel.php | 24 +++++- include/connections.php | 13 +++ include/import.php | 58 +++++++++++++ include/security.php | 28 +++++-- include/text.php | 2 +- install/schema_mysql.sql | 2 + install/schema_postgres.sql | 2 + view/tpl/tokens.tpl | 7 +- 10 files changed, 282 insertions(+), 50 deletions(-) diff --git a/Zotlabs/Module/Tokens.php b/Zotlabs/Module/Tokens.php index 31b219019..632e816ce 100644 --- a/Zotlabs/Module/Tokens.php +++ b/Zotlabs/Module/Tokens.php @@ -5,6 +5,11 @@ namespace Zotlabs\Module; use App; use Zotlabs\Web\Controller; use Zotlabs\Lib\Apps; +use Zotlabs\Lib\AccessList; +use Zotlabs\Lib\Permcat; +use Zotlabs\Lib\Libsync; + +require_once('include/security.php'); class Tokens extends Controller { @@ -13,15 +18,20 @@ class Tokens extends Controller { if(! local_channel()) return; - if(! Apps::system_app_installed(local_channel(), 'Guest Access')) - return; - $channel = App::get_channel(); + if(! Apps::system_app_installed($channel['channel_id'], 'Guest Access')) + return; + check_form_security_token_redirectOnErr('tokens', 'tokens'); $token_errs = 0; if(array_key_exists('token',$_POST)) { $atoken_id = (($_POST['atoken_id']) ? intval($_POST['atoken_id']) : 0); + + if (! $atoken_id) { + $atoken_guid = new_uuid(); + } + $name = trim(escape_tags($_POST['name'])); $token = trim($_POST['token']); if((! $name) || (! $token)) @@ -30,10 +40,10 @@ class Tokens extends Controller { $expires = datetime_convert(date_default_timezone_get(),'UTC',$_POST['expires']); else $expires = NULL_DATE; - $max_atokens = service_class_fetch(local_channel(),'access_tokens'); + $max_atokens = service_class_fetch($channel['channel_id'],'access_tokens'); if($max_atokens) { $r = q("select count(atoken_id) as total where atoken_uid = %d", - intval(local_channel()) + intval($channel['channel_id']) ); if($r && intval($r[0]['total']) >= $max_tokens) { notice( sprintf( t('This channel is limited to %d tokens'), $max_tokens) . EOL); @@ -45,6 +55,17 @@ class Tokens extends Controller { notice( t('Name and Password are required.') . EOL); return; } + + $old_atok = q("select * from atoken where atoken_uid = %d and atoken_name = '%s'", + intval($channel['channel_id']), + dbesc($name) + ); + + if ($old_atok) { + $old_atok = $old_atok[0]; + $old_xchan = atoken_xchan($old_atok); + } + if($atoken_id) { $r = q("update atoken set atoken_name = '%s', atoken_token = '%s', atoken_expires = '%s' where atoken_id = %d and atoken_uid = %d", @@ -56,8 +77,9 @@ class Tokens extends Controller { ); } else { - $r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires ) - values ( %d, %d, '%s', '%s', '%s' ) ", + $r = q("insert into atoken (atoken_guid, atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires ) + values ('%s', %d, %d, '%s', '%s', '%s' ) ", + dbesc($atoken_guid), intval($channel['channel_account_id']), intval($channel['channel_id']), dbesc($name), @@ -66,21 +88,85 @@ class Tokens extends Controller { ); } - $atoken_xchan = substr($channel['channel_hash'],0,16) . '.' . $name; + $atok = q("select * from atoken where atoken_uid = %d and atoken_name = '%s'", + intval($channel['channel_id']), + dbesc($name) + ); - $all_perms = \Zotlabs\Access\Permissions::Perms(); + if ($atok) { + $xchan = atoken_xchan($atok[0]); + atoken_create_xchan($xchan); + $atoken_xchan = $xchan['xchan_hash']; + if ($old_atok && $old_xchan) { + $r = q("update xchan set xchan_name = '%s' where xchan_hash = '%s'", + dbesc($xchan['xchan_name']), + dbesc($old_xchan['xchan_hash']) + ); + } + } - if($all_perms) { - foreach($all_perms as $perm => $desc) { - if(array_key_exists('perms_' . $perm, $_POST)) { - set_abconfig($channel['channel_id'],$atoken_xchan,'my_perms',$perm,intval($_POST['perms_' . $perm])); - } - else { - set_abconfig($channel['channel_id'],$atoken_xchan,'my_perms',$perm,0); + + if (! $atoken_id) { + + // If this is a new token, create a new abook record + + $closeness = get_pconfig($uid,'system','new_abook_closeness',80); + $profile_assign = get_pconfig($uid,'system','profile_assign',''); + + $r = abook_store_lowlevel( + [ + 'abook_account' => $channel['channel_account_id'], + 'abook_channel' => $channel['channel_id'], + 'abook_closeness' => intval($closeness), + 'abook_xchan' => $atoken_xchan, + 'abook_profile' => $profile_assign, + 'abook_feed' => 0, + 'abook_created' => datetime_convert(), + 'abook_updated' => datetime_convert(), + 'abook_instance' => z_root(), + ] + ); + + if (! $r) { + logger('abook creation failed'); + } + + /** If there is a default group for this channel, add this connection to it */ + + if ($channel['channel_default_group']) { + $g = AccessList::by_hash($uid,$channel['channel_default_group']); + if ($g) { + AccessList::member_add($uid,'',$atoken_xchan,$g['id']); } } } + $role = ((array_key_exists('permcat', $_POST)) ? escape_tags($_POST['permcat']) : ''); + \Zotlabs\Lib\Permcat::assign($channel, $role, [$atoken_xchan]); + + $r = q("SELECT abook.*, xchan.* + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and abook_xchan = '%s' LIMIT 1", + intval($channel['chnnel_id']), + dbesc($atoken_xchan) + ); + + if (! $r) { + return; + } + + $clone = $r[0]; + + unset($clone['abook_id']); + unset($clone['abook_account']); + unset($clone['abook_channel']); + + $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); + if ($abconfig) { + $clone['abconfig'] = $abconfig; + } + + Libsync::build_sync_packet($channel['channel_id'], [ 'abook' => [ $clone ], 'atoken' => $atok ], true); info( t('Token saved.') . EOL); return; @@ -103,6 +189,7 @@ class Tokens extends Controller { $atoken = null; $atoken_xchan = ''; + $atoken_abook = []; if(argc() > 1) { $id = argv(1); @@ -114,13 +201,47 @@ class Tokens extends Controller { if($atoken) { $atoken = $atoken[0]; - $atoken_xchan = substr($channel['channel_hash'],0,16) . '.' . $atoken['atoken_name']; + $atoken_xchan = substr($channel['channel_hash'],0,16) . '.' . $atoken['atoken_guid']; + + $atoken_abook = q("select * from abook where abook_channel = %d and abook_xchan = '%s'", + intval(local_channel()), + dbesc($atoken_xchan) + ); + + $atoken_abook = $atoken_abook[0]; } if($atoken && argc() > 2 && argv(2) === 'drop') { + $atoken['deleted'] = true; + + $r = q("SELECT abook.*, xchan.* + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel = %d and abook_xchan = '%s' LIMIT 1", + intval($channel['chnnel_id']), + dbesc($atoken_xchan) + ); + if (! $r) { + return; + } + + $clone = $r[0]; + + unset($clone['abook_id']); + unset($clone['abook_account']); + unset($clone['abook_channel']); + $clone['deleted'] = true; + + $abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']); + if ($abconfig) { + $clone['abconfig'] = $abconfig; + } + atoken_delete($id); + Libsync::build_sync_packet($channel['channel_id'], [ 'abook' => [ $clone ], 'atoken' => [ $atoken ] ], true); + $atoken = null; $atoken_xchan = ''; + $atoken_abook = null; } } @@ -132,39 +253,34 @@ class Tokens extends Controller { $desc2 = t('You may also provide dropbox style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:'); - $global_perms = \Zotlabs\Access\Permissions::Perms(); - $their_perms = []; - $existing = get_all_perms(local_channel(),(($atoken_xchan) ? $atoken_xchan : ''),false); + //TODO: assign role + $pcat = new Permcat(local_channel()); + $pcatlist = $pcat->listing(); + $default_role = get_pconfig(local_channel(), 'system', 'default_permcat'); + $current_permcat = (($atoken_abook) ? $atoken_abook['abook_role'] : $default_role); - if($atoken_xchan) { - $theirs = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'their_perms'", - intval(local_channel()), - dbesc($atoken_xchan) - ); - if($theirs) { - foreach($theirs as $t) { - $their_perms[$t['k']] = $t['v']; - } - } + $roles_dict = []; + foreach ($pcatlist as $role) { + $roles_dict[$role['name']] = $role['localname']; } - foreach($global_perms as $k => $v) { - $thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k); -//fixme - - $checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k); - if($existing[$k]) - $thisperm = "1"; - $perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited); + if (!$current_permcat) { + notice(t('Please select a role for this contact!') . EOL); + $permcats[] = ''; } - + if ($pcatlist) { + foreach ($pcatlist as $pc) { + $permcats[$pc['name']] = $pc['localname']; + } + } $tpl = get_markup_template("tokens.tpl"); $o .= replace_macros($tpl, array( '$form_security_token' => get_form_security_token("tokens"), + '$permcat' => ['permcat', t('Select a role for this token'), $current_permcat, '', $permcats], '$title' => t('Guest Access Tokens'), '$desc' => $desc, '$desc2' => $desc2, diff --git a/boot.php b/boot.php index 838c93177..91f0b8147 100644 --- a/boot.php +++ b/boot.php @@ -58,7 +58,7 @@ define ( 'PLATFORM_NAME', 'hubzilla' ); define ( 'STD_VERSION', '6.5.10' ); define ( 'ZOT_REVISION', '6.0' ); -define ( 'DB_UPDATE_VERSION', 1249 ); +define ( 'DB_UPDATE_VERSION', 1250 ); define ( 'PROJECT_BASE', __DIR__ ); diff --git a/include/channel.php b/include/channel.php index 00d973738..c80a35385 100644 --- a/include/channel.php +++ b/include/channel.php @@ -21,6 +21,7 @@ require_once('include/crypto.php'); require_once('include/menu.php'); require_once('include/perm_upgrade.php'); require_once('include/photo/photo_driver.php'); +require_once('include/security.php'); /** * @brief Called when creating a new channel. @@ -878,6 +879,14 @@ function identity_basic_export($channel_id, $sections = null, $zap_compat = fals } if(in_array('connections',$sections)) { + $r = q("select * from atoken where atoken_uid = %d", + intval($channel_id) + ); + + if ($r) { + $ret['atoken'] = $r; + } + $xchans = array(); $r = q("select * from abook where abook_channel = %d ", intval($channel_id) @@ -1963,11 +1972,24 @@ function zat_init() { ); if($r) { $xchan = atoken_xchan($r[0]); - atoken_create_xchan($xchan); + //atoken_create_xchan($xchan); atoken_login($xchan); } } +function atoken_delete_and_sync($channel_id, $atoken_guid) { + $r = q("select * from atoken where atoken_guid = '%s' and atoken_uid = %d", + dbesc($atoken_guid), + intval($channel_id) + ); + + if ($r) { + $atok = $r[0]; + $atok['deleted'] = true; + atoken_delete($atok['atoken_id']); + Libsync::build_sync_packet($channel_id, ['atoken' => [ $atok ]]); + } +} /** * @brief Used from within PCSS themes to set theme parameters. diff --git a/include/connections.php b/include/connections.php index 11264e6d8..fbbf59c72 100644 --- a/include/connections.php +++ b/include/connections.php @@ -376,6 +376,19 @@ function contact_remove($channel_id, $abook_id) { if(intval($abook['abook_self'])) return false; + // if this is an atoken, delete the atoken record + + $xchan = q("select * from xchan where xchan_hash = '%s'", + dbesc($abook['abook_xchan']) + ); + + if (strpos($xchan['xchan_addr'],'guest:') === 0 && strpos($abook['abook_xchan'],'.')){ + $atoken_guid = substr($abook['abook_xchan'],strrpos($abook['abook_xchan'],'.') + 1); + if ($atoken_guid) { + atoken_delete_and_sync($channel_id,$atoken_guid); + } + } + $r = q("select id, parent from item where (owner_xchan = '%s' or author_xchan = '%s') and uid = %d and item_retained = 0 and item_starred = 0", dbesc($abook['abook_xchan']), dbesc($abook['abook_xchan']), diff --git a/include/import.php b/include/import.php index 8707a9430..291dd2638 100644 --- a/include/import.php +++ b/include/import.php @@ -162,6 +162,64 @@ function import_config($channel, $configs) { } } +function import_atoken($channel, $atokens) { + if ($channel && $atokens) { + foreach ($atokens as $atoken) { + unset($atoken['atoken_id']); + $atoken['atoken_aid'] = $channel['channel_account_id']; + $atoken['atoken_uid'] = $channel['channel_id']; + create_table_from_array('atoken', $atoken); + } + } +} + +function sync_atoken($channel, $atokens) { + + if ($channel && $atokens) { + foreach ($atokens as $atoken) { + unset($atoken['atoken_id']); + $atoken['atoken_aid'] = $channel['channel_account_id']; + $atoken['atoken_uid'] = $channel['channel_id']; + + if ($atoken['deleted']) { + q("delete from atoken where atoken_uid = %d and atoken_guid = '%s' ", + intval($atoken['atoken_uid']), + dbesc($atoken['atoken_guid']) + ); + continue; + } + + $r = q("select * from atoken where atoken_uid = %d and atoken_guid = '%s' ", + intval($atoken['atoken_uid']), + dbesc($atoken['atoken_guid']) + ); + if (! $r) { + create_table_from_array('atoken', $atoken); + } + else { + $columns = db_columns('atoken'); + foreach ($atoken as $k => $v) { + if (! in_array($k,$columns)) { + continue; + } + + if (in_array($k, ['atoken_guid','atoken_uid','atoken_aid'])) { + continue; + } + + $r = q("UPDATE atoken SET " . TQUOT . "%s" . TQUOT . " = '%s' WHERE atoken_guid = '%s' AND atoken_uid = %d", + dbesc($k), + dbesc($v), + dbesc($atoken['atoken_guid']), + intval($channel['channel_id']) + ); + } + } + } + } +} + + /** * @brief Import profiles. * diff --git a/include/security.php b/include/security.php index b6c0f1511..f02fb8023 100644 --- a/include/security.php +++ b/include/security.php @@ -89,8 +89,20 @@ function authenticate_success($user_record, $channel = null, $login_initial = fa } function atoken_login($atoken) { - if (!$atoken) + if (! $atoken) { return false; + } + + if (App::$cmd === 'channel' && argv(1)) { + $channel = channelx_by_nick(argv(1)); + if (perm_is_allowed($channel['channel_id'],$atoken['xchan_hash'],'delegate')) { + $_SESSION['delegate_channel'] = $channel['channel_id']; + $_SESSION['delegate'] = $atoken['xchan_hash']; + $_SESSION['account_id'] = intval($channel['channel_account_id']); + change_channel($channel['channel_id']); + return; + } + } $_SESSION['authenticated'] = 1; $_SESSION['visitor_id'] = $atoken['xchan_hash']; @@ -113,11 +125,11 @@ function atoken_xchan($atoken) { if ($c) { return [ 'atoken_id' => $atoken['atoken_id'], - 'xchan_hash' => substr($c['channel_hash'], 0, 16) . '.' . $atoken['atoken_name'], + 'xchan_hash' => substr($c['channel_hash'], 0, 16) . '.' . $atoken['atoken_guid'], 'xchan_name' => $atoken['atoken_name'], 'xchan_addr' => 'guest:' . $atoken['atoken_name'] . '@' . App::get_hostname(), 'xchan_network' => 'unknown', - 'xchan_url' => z_root() . '/guest/' . substr($c['channel_hash'], 0, 16) . '.' . $atoken['atoken_name'], + 'xchan_url' => z_root() . '/guest/' . substr($c['channel_hash'], 0, 16) . '.' . $atoken['atoken_guid'], 'xchan_hidden' => 1, 'xchan_photo_mimetype' => 'image/png', 'xchan_photo_l' => z_root() . '/' . get_default_profile_photo(300), @@ -143,11 +155,17 @@ function atoken_delete($atoken_id) { if (!$c) return; - $atoken_xchan = substr($c[0]['channel_hash'], 0, 16) . '.' . $r[0]['atoken_name']; + $atoken_xchan = substr($c[0]['channel_hash'], 0, 16) . '.' . $r[0]['atoken_guid']; q("delete from atoken where atoken_id = %d", intval($atoken_id) ); + + q("delete from abook where abook_channel = %d and abook_xchan = '%s'", + intval($c[0]['channel_id']), + dbesc($atoken_xchan) + ); + q("delete from abconfig where chan = %d and xchan = '%s'", intval($c[0]['channel_id']), dbesc($atoken_xchan) @@ -198,7 +216,7 @@ function atoken_abook($uid, $xchan_hash) { if (!$r) return false; - $x = q("select * from atoken where atoken_uid = %d and atoken_name = '%s'", + $x = q("select * from atoken where atoken_uid = %d and atoken_guid = '%s'", intval($uid), dbesc(substr($xchan_hash, 17)) ); diff --git a/include/text.php b/include/text.php index b2b3fce6e..84f112802 100644 --- a/include/text.php +++ b/include/text.php @@ -1715,7 +1715,7 @@ function prepare_body(&$item,$attach = false,$opts = false) { if ($is_photo) { $object = json_decode($item['obj'],true); $ptr = null; - if (array_key_exists('url',$object) && is_array($object['url'])) { + if (is_array($object) && array_key_exists('url',$object) && is_array($object['url'])) { if (array_key_exists(0,$object['url'])) { foreach ($object['url'] as $link) { if(array_key_exists('width',$link) && $link['width'] >= 640 && $link['width'] <= 1024) { diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql index 054c1da03..80ae20d7b 100644 --- a/install/schema_mysql.sql +++ b/install/schema_mysql.sql @@ -148,12 +148,14 @@ CREATE TABLE IF NOT EXISTS `app` ( CREATE TABLE IF NOT EXISTS `atoken` ( `atoken_id` int(11) NOT NULL AUTO_INCREMENT, + `atoken_guid` char(191) NOT NULL DEFAULT '', `atoken_aid` int(11) NOT NULL DEFAULT 0 , `atoken_uid` int(11) NOT NULL DEFAULT 0 , `atoken_name` char(191) NOT NULL DEFAULT '', `atoken_token` char(191) NOT NULL DEFAULT '', `atoken_expires` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY (`atoken_id`), + KEY `atoken_guid` (`atoken_guid`), KEY `atoken_aid` (`atoken_aid`), KEY `atoken_uid` (`atoken_uid`), KEY `atoken_uid_2` (`atoken_uid`), diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql index c1cbc832b..96d0cc33c 100644 --- a/install/schema_postgres.sql +++ b/install/schema_postgres.sql @@ -147,12 +147,14 @@ create index "app_system" on app ("app_system"); CREATE TABLE "atoken" ( "atoken_id" serial NOT NULL, + "atoken_guid" varchar(255) NOT NULL DEFAULT '', "atoken_aid" bigint NOT NULL DEFAULT 0, "atoken_uid" bigint NOT NULL DEFAULT 0, "atoken_name" varchar(255) NOT NULL DEFAULT '', "atoken_token" varchar(255) NOT NULL DEFAULT '', "atoken_expires" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY ("atoken_id")); +create index atoken_guid on atoken (atoken_guid); create index atoken_aid on atoken (atoken_aid); create index atoken_uid on atoken (atoken_uid); create index atoken_name on atoken (atoken_name); diff --git a/view/tpl/tokens.tpl b/view/tpl/tokens.tpl index 6bf8dc202..51cd4a6cf 100644 --- a/view/tpl/tokens.tpl +++ b/view/tpl/tokens.tpl @@ -14,12 +14,14 @@ {{include file="field_input.tpl" field=$name}} {{include file="field_input.tpl" field=$token}} {{include file="field_input.tpl" field=$expires}} + {{include file="field_select.tpl" field=$permcat}} +
-
+
{{$desc2}}
    -- cgit v1.2.3 From 2bd69495d2bfce0481e47421cee700aa08eee54f Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 17 Dec 2021 19:52:54 +0100 Subject: missing file --- Zotlabs/Update/_1250.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Zotlabs/Update/_1250.php diff --git a/Zotlabs/Update/_1250.php b/Zotlabs/Update/_1250.php new file mode 100644 index 000000000..bc50479d4 --- /dev/null +++ b/Zotlabs/Update/_1250.php @@ -0,0 +1,31 @@ + Date: Fri, 17 Dec 2021 19:25:28 +0000 Subject: daemon to delete abbok items in the background --- Zotlabs/Daemon/Delxitems.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Zotlabs/Daemon/Delxitems.php diff --git a/Zotlabs/Daemon/Delxitems.php b/Zotlabs/Daemon/Delxitems.php new file mode 100644 index 000000000..264354ca0 --- /dev/null +++ b/Zotlabs/Daemon/Delxitems.php @@ -0,0 +1,25 @@ + Date: Fri, 17 Dec 2021 20:26:36 +0100 Subject: implement background deleting of items in contact_remove() --- include/connections.php | 103 +++++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/include/connections.php b/include/connections.php index fbbf59c72..98cd4bbb5 100644 --- a/include/connections.php +++ b/include/connections.php @@ -1,5 +1,6 @@ Date: Fri, 17 Dec 2021 22:05:45 +0100 Subject: mod tokens cleanup and fixes --- Zotlabs/Module/Tokens.php | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/Zotlabs/Module/Tokens.php b/Zotlabs/Module/Tokens.php index 632e816ce..b1c8bb4bf 100644 --- a/Zotlabs/Module/Tokens.php +++ b/Zotlabs/Module/Tokens.php @@ -110,8 +110,8 @@ class Tokens extends Controller { // If this is a new token, create a new abook record - $closeness = get_pconfig($uid,'system','new_abook_closeness',80); - $profile_assign = get_pconfig($uid,'system','profile_assign',''); + $closeness = get_pconfig($channel['channel_id'], 'system', 'new_abook_closeness',80); + $profile_assign = get_pconfig($channel['channel_id'], 'system', 'profile_assign', ''); $r = abook_store_lowlevel( [ @@ -132,11 +132,10 @@ class Tokens extends Controller { } /** If there is a default group for this channel, add this connection to it */ - if ($channel['channel_default_group']) { - $g = AccessList::by_hash($uid,$channel['channel_default_group']); + $g = AccessList::by_hash($channel['channel_id'], $channel['channel_default_group']); if ($g) { - AccessList::member_add($uid,'',$atoken_xchan,$g['id']); + AccessList::member_add($channel['channel_id'], '', $atoken_xchan,$g['id']); } } } @@ -281,8 +280,8 @@ class Tokens extends Controller { $o .= replace_macros($tpl, array( '$form_security_token' => get_form_security_token("tokens"), '$permcat' => ['permcat', t('Select a role for this token'), $current_permcat, '', $permcats], - '$title' => t('Guest Access Tokens'), - '$desc' => $desc, + '$title' => t('Guest Access Tokens'), + '$desc' => $desc, '$desc2' => $desc2, '$tokens' => $t, '$atoken' => $atoken, @@ -291,15 +290,7 @@ class Tokens extends Controller { '$name' => array('name', t('Login Name') . ' *', (($atoken) ? $atoken['atoken_name'] : ''),''), '$token'=> array('token', t('Login Password') . ' *',(($atoken) ? $atoken['atoken_token'] : autoname(8)), ''), '$expires'=> array('expires', t('Expires (yyyy-mm-dd)'), (($atoken['atoken_expires'] && $atoken['atoken_expires'] > NULL_DATE) ? datetime_convert('UTC',date_default_timezone_get(),$atoken['atoken_expires']) : ''), ''), - '$them' => t('Their Settings'), - '$me' => t('My Settings'), - '$perms' => $perms, - '$inherited' => t('inherited'), - '$notself' => 1, - '$self' => 0, - '$permlbl' => t('Individual Permissions'), - '$permnote' => t('Some permissions may be inherited from your channel\'s privacy settings, which have higher priority than individual settings. You can not change those settings here.'), - '$submit' => t('Submit') + '$submit' => t('Submit') )); return $o; } -- cgit v1.2.3 From 565602538c28b7fd2e172b4ea6fdc0c907202842 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 17 Dec 2021 21:08:20 +0000 Subject: main.js simplify notify_id checks --- Zotlabs/Lib/ZotURL.php | 2 +- view/js/main.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zotlabs/Lib/ZotURL.php b/Zotlabs/Lib/ZotURL.php index 6bb01fd7a..db0071f72 100644 --- a/Zotlabs/Lib/ZotURL.php +++ b/Zotlabs/Lib/ZotURL.php @@ -87,4 +87,4 @@ class ZotURL { return ids_to_array($r,'hubloc_url'); } -} \ No newline at end of file +} diff --git a/view/js/main.js b/view/js/main.js index f4f641e33..f7709f9d1 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -178,7 +178,7 @@ $(document).ready(function() { path = 'hq'; } - if(notify_id != null) { + if(notify_id) { $.ajax({ type: 'post', url: 'notify', @@ -999,7 +999,7 @@ function liveUpdate(notify_id) { // else data was valid - reset the recursion counter liveRecurse = 0; - if(typeof notify_id !== 'undefined' && notify_id !== 'undefined') { + if(notify_id) { $.post( "notify", { -- cgit v1.2.3 From 9c79b5be77da7e5626ca7f0671fe5ed9b1f9c955 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 17 Dec 2021 21:10:00 +0000 Subject: version --- boot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot.php b/boot.php index 91f0b8147..ed2397b43 100644 --- a/boot.php +++ b/boot.php @@ -55,7 +55,7 @@ require_once('include/bbcode.php'); require_once('include/items.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '6.5.10' ); +define ( 'STD_VERSION', '6.5.11' ); define ( 'ZOT_REVISION', '6.0' ); define ( 'DB_UPDATE_VERSION', 1250 ); -- cgit v1.2.3 From 9c790e5a900b3b3ea3746b761ffad6d8f30eda24 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Sat, 18 Dec 2021 00:39:47 +0200 Subject: Update Russian translation --- view/ru/hmessages.po | 3547 ++++++++++++++++++++++++++------------------------ view/ru/hstrings.php | 322 +++-- 2 files changed, 2056 insertions(+), 1813 deletions(-) diff --git a/view/ru/hmessages.po b/view/ru/hmessages.po index 2a856aa2f..ec63bc1ba 100644 --- a/view/ru/hmessages.po +++ b/view/ru/hmessages.po @@ -6,10 +6,10 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: 6.2RC\n" +"Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-05 20:30+0200\n" -"PO-Revision-Date: 2021-10-05 20:35+0200\n" +"POT-Creation-Date: 2021-12-17 23:32+0200\n" +"PO-Revision-Date: 2021-12-17 23:40+0200\n" "Last-Translator: Max Kostikov \n" "Language-Team: Russian (http://www.transifex.com/Friendica/hubzilla/language/ru/)\n" "MIME-Version: 1.0\n" @@ -18,59 +18,69 @@ msgstr "" "Language: ru\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2))\n" -#: ../../boot.php:1704 +#: ../../boot.php:1705 msgid "Create an account to access services and applications" msgstr "Создайте аккаунт для доступа к службам и приложениям" -#: ../../boot.php:1705 ../../Zotlabs/Module/Register.php:542 -#: ../../include/nav.php:165 +#: ../../boot.php:1706 ../../Zotlabs/Module/Register.php:542 +#: ../../include/nav.php:163 msgid "Register" msgstr "Регистрация" -#: ../../boot.php:1722 +#: ../../boot.php:1723 msgid "Email or nickname" msgstr "Электронная почта или псевдоним" -#: ../../boot.php:1722 ../../extend/addon/hzaddons/redred/Mod_Redred.php:73 +#: ../../boot.php:1723 ../../extend/addon/hzaddons/redred/Mod_Redred.php:73 #: ../../extend/addon/hzaddons/openid/MysqlProvider.php:54 msgid "Nickname" msgstr "Псевдоним" -#: ../../boot.php:1727 ../../include/nav.php:109 ../../include/nav.php:139 -#: ../../include/nav.php:160 +#: ../../boot.php:1728 ../../include/nav.php:107 ../../include/nav.php:137 +#: ../../include/nav.php:158 msgid "Logout" msgstr "Выход" -#: ../../boot.php:1728 ../../Zotlabs/Lib/Apps.php:342 ../../include/nav.php:124 -#: ../../include/nav.php:128 +#: ../../boot.php:1729 ../../Zotlabs/Lib/Apps.php:342 ../../include/nav.php:122 +#: ../../include/nav.php:126 msgid "Login" msgstr "Войти" -#: ../../boot.php:1729 ../../Zotlabs/Module/Rmagic.php:96 -#: ../../include/channel.php:2561 +#: ../../boot.php:1730 ../../Zotlabs/Module/Rmagic.php:96 +#: ../../include/channel.php:2610 msgid "Remote Authentication" msgstr "Удаленная аутентификация" -#: ../../boot.php:1732 +#: ../../boot.php:1733 msgid "Password" msgstr "Пароль" -#: ../../boot.php:1733 +#: ../../boot.php:1734 msgid "Remember me" msgstr "Запомнить меня" -#: ../../boot.php:1733 ../../Zotlabs/Module/Register.php:512 +#: ../../boot.php:1734 ../../Zotlabs/Module/Register.php:512 #: ../../Zotlabs/Module/Photos.php:677 ../../Zotlabs/Module/Admin/Site.php:319 #: ../../Zotlabs/Module/Sources.php:122 ../../Zotlabs/Module/Sources.php:157 -#: ../../Zotlabs/Module/Profiles.php:683 ../../Zotlabs/Module/Defperms.php:196 -#: ../../Zotlabs/Module/Api.php:99 ../../Zotlabs/Module/Filestorage.php:203 +#: ../../Zotlabs/Module/Profiles.php:701 ../../Zotlabs/Module/Profiles.php:711 +#: ../../Zotlabs/Module/Profiles.php:719 ../../Zotlabs/Module/Profiles.php:723 +#: ../../Zotlabs/Module/Defperms.php:195 ../../Zotlabs/Module/Api.php:99 +#: ../../Zotlabs/Module/Filestorage.php:203 #: ../../Zotlabs/Module/Filestorage.php:211 +#: ../../Zotlabs/Module/Permcats.php:232 +#: ../../Zotlabs/Module/Settings/Privacy.php:120 +#: ../../Zotlabs/Module/Settings/Privacy.php:121 +#: ../../Zotlabs/Module/Settings/Privacy.php:122 #: ../../Zotlabs/Module/Settings/Display.php:86 -#: ../../Zotlabs/Module/Settings/Channel.php:313 -#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 -#: ../../Zotlabs/Module/Import.php:591 ../../Zotlabs/Module/Import.php:595 -#: ../../Zotlabs/Module/Import.php:596 ../../Zotlabs/Module/Connedit.php:401 -#: ../../Zotlabs/Module/Connedit.php:781 ../../Zotlabs/Module/Mitem.php:176 +#: ../../Zotlabs/Module/Settings/Channel.php:219 +#: ../../Zotlabs/Module/Contactedit.php:284 +#: ../../Zotlabs/Module/Contactedit.php:329 ../../Zotlabs/Module/Menu.php:163 +#: ../../Zotlabs/Module/Menu.php:222 ../../Zotlabs/Module/Import.php:600 +#: ../../Zotlabs/Module/Import.php:604 ../../Zotlabs/Module/Import.php:605 +#: ../../Zotlabs/Module/Group.php:151 ../../Zotlabs/Module/Group.php:152 +#: ../../Zotlabs/Module/Group.php:163 ../../Zotlabs/Module/Group.php:275 +#: ../../Zotlabs/Module/Group.php:330 ../../Zotlabs/Module/Group.php:331 +#: ../../Zotlabs/Module/Connedit.php:622 ../../Zotlabs/Module/Mitem.php:176 #: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:256 #: ../../Zotlabs/Module/Mitem.php:257 ../../Zotlabs/Module/Wiki.php:224 #: ../../Zotlabs/Module/Wiki.php:225 ../../Zotlabs/Storage/Browser.php:310 @@ -78,7 +88,7 @@ msgstr "Запомнить меня" #: ../../Zotlabs/Storage/Browser.php:389 ../../Zotlabs/Storage/Browser.php:391 #: ../../Zotlabs/Storage/Browser.php:552 ../../Zotlabs/Lib/Libzotdir.php:165 #: ../../Zotlabs/Lib/Libzotdir.php:166 ../../Zotlabs/Lib/Libzotdir.php:168 -#: ../../include/conversation.php:1472 +#: ../../include/conversation.php:1486 #: ../../view/theme/redbasic/php/config.php:99 #: ../../view/theme/redbasic/php/config.php:116 #: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111 @@ -97,9 +107,9 @@ msgstr "Запомнить меня" #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:362 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:438 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:462 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:66 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:650 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:654 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:67 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:651 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:655 #: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153 #: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425 #: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87 @@ -132,17 +142,26 @@ msgstr "Запомнить меня" msgid "No" msgstr "Нет" -#: ../../boot.php:1733 ../../Zotlabs/Module/Register.php:512 +#: ../../boot.php:1734 ../../Zotlabs/Module/Register.php:512 #: ../../Zotlabs/Module/Photos.php:677 ../../Zotlabs/Module/Admin/Site.php:321 #: ../../Zotlabs/Module/Sources.php:122 ../../Zotlabs/Module/Sources.php:157 -#: ../../Zotlabs/Module/Profiles.php:683 ../../Zotlabs/Module/Defperms.php:196 -#: ../../Zotlabs/Module/Api.php:98 ../../Zotlabs/Module/Filestorage.php:203 +#: ../../Zotlabs/Module/Profiles.php:701 ../../Zotlabs/Module/Profiles.php:711 +#: ../../Zotlabs/Module/Profiles.php:719 ../../Zotlabs/Module/Profiles.php:723 +#: ../../Zotlabs/Module/Defperms.php:195 ../../Zotlabs/Module/Api.php:98 +#: ../../Zotlabs/Module/Filestorage.php:203 #: ../../Zotlabs/Module/Filestorage.php:211 +#: ../../Zotlabs/Module/Permcats.php:232 +#: ../../Zotlabs/Module/Settings/Privacy.php:120 +#: ../../Zotlabs/Module/Settings/Privacy.php:121 +#: ../../Zotlabs/Module/Settings/Privacy.php:122 #: ../../Zotlabs/Module/Settings/Display.php:86 -#: ../../Zotlabs/Module/Settings/Channel.php:313 -#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:222 -#: ../../Zotlabs/Module/Import.php:591 ../../Zotlabs/Module/Import.php:595 -#: ../../Zotlabs/Module/Import.php:596 ../../Zotlabs/Module/Connedit.php:401 +#: ../../Zotlabs/Module/Settings/Channel.php:219 +#: ../../Zotlabs/Module/Contactedit.php:284 ../../Zotlabs/Module/Menu.php:163 +#: ../../Zotlabs/Module/Menu.php:222 ../../Zotlabs/Module/Import.php:600 +#: ../../Zotlabs/Module/Import.php:604 ../../Zotlabs/Module/Import.php:605 +#: ../../Zotlabs/Module/Group.php:151 ../../Zotlabs/Module/Group.php:152 +#: ../../Zotlabs/Module/Group.php:163 ../../Zotlabs/Module/Group.php:275 +#: ../../Zotlabs/Module/Group.php:330 ../../Zotlabs/Module/Group.php:331 #: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:177 #: ../../Zotlabs/Module/Mitem.php:256 ../../Zotlabs/Module/Mitem.php:257 #: ../../Zotlabs/Module/Wiki.php:224 ../../Zotlabs/Module/Wiki.php:225 @@ -150,7 +169,7 @@ msgstr "Нет" #: ../../Zotlabs/Storage/Browser.php:312 ../../Zotlabs/Storage/Browser.php:389 #: ../../Zotlabs/Storage/Browser.php:391 ../../Zotlabs/Storage/Browser.php:552 #: ../../Zotlabs/Lib/Libzotdir.php:165 ../../Zotlabs/Lib/Libzotdir.php:166 -#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/conversation.php:1472 +#: ../../Zotlabs/Lib/Libzotdir.php:168 ../../include/conversation.php:1486 #: ../../view/theme/redbasic/php/config.php:99 #: ../../view/theme/redbasic/php/config.php:116 #: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111 @@ -169,9 +188,9 @@ msgstr "Нет" #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:361 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:437 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:461 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:66 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:650 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:654 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:67 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:651 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:655 #: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153 #: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425 #: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87 @@ -204,55 +223,55 @@ msgstr "Нет" msgid "Yes" msgstr "Да" -#: ../../boot.php:1736 +#: ../../boot.php:1737 msgid "Forgot your password?" msgstr "Забыли пароль или логин?" -#: ../../boot.php:1737 ../../Zotlabs/Module/Lostpass.php:91 +#: ../../boot.php:1738 ../../Zotlabs/Module/Lostpass.php:91 msgid "Password Reset" msgstr "Сбросить пароль" -#: ../../boot.php:2615 +#: ../../boot.php:2616 #, php-format msgid "[$Projectname] Website SSL error for %s" msgstr "[$Projectname] Ошибка SSL/TLS веб-сайта для %s" -#: ../../boot.php:2620 +#: ../../boot.php:2621 msgid "Website SSL certificate is not valid. Please correct." msgstr "SSL/TLS сертификат веб-сайт недействителен. Исправьте это." -#: ../../boot.php:2736 +#: ../../boot.php:2737 #, php-format msgid "[$Projectname] Cron tasks not running on %s" msgstr "[$Projectname] Задания Cron не запущены на %s" -#: ../../boot.php:2741 +#: ../../boot.php:2742 msgid "Cron/Scheduled tasks not running." msgstr "Задания Cron / планировщика не запущены." -#: ../../boot.php:2742 ../../include/datetime.php:238 +#: ../../boot.php:2743 ../../include/datetime.php:238 msgid "never" msgstr "никогда" #: ../../Zotlabs/Module/Viewsrc.php:19 ../../Zotlabs/Module/Block.php:24 -#: ../../Zotlabs/Module/Block.php:74 ../../Zotlabs/Module/Channel.php:217 -#: ../../Zotlabs/Module/Channel.php:373 ../../Zotlabs/Module/Channel.php:412 +#: ../../Zotlabs/Module/Block.php:74 ../../Zotlabs/Module/Channel.php:220 +#: ../../Zotlabs/Module/Channel.php:376 ../../Zotlabs/Module/Channel.php:415 #: ../../Zotlabs/Module/Register.php:200 ../../Zotlabs/Module/Photos.php:71 -#: ../../Zotlabs/Module/Appman.php:91 ../../Zotlabs/Module/Item.php:507 -#: ../../Zotlabs/Module/Item.php:526 ../../Zotlabs/Module/Item.php:536 -#: ../../Zotlabs/Module/Item.php:1451 ../../Zotlabs/Module/Sources.php:80 +#: ../../Zotlabs/Module/Appman.php:153 ../../Zotlabs/Module/Item.php:501 +#: ../../Zotlabs/Module/Item.php:520 ../../Zotlabs/Module/Item.php:530 +#: ../../Zotlabs/Module/Item.php:1444 ../../Zotlabs/Module/Sources.php:80 #: ../../Zotlabs/Module/Poke.php:157 ../../Zotlabs/Module/Card_edit.php:51 -#: ../../Zotlabs/Module/Profiles.php:200 ../../Zotlabs/Module/Profiles.php:637 +#: ../../Zotlabs/Module/Profiles.php:199 ../../Zotlabs/Module/Profiles.php:646 #: ../../Zotlabs/Module/Connections.php:32 -#: ../../Zotlabs/Module/Profile_photo.php:338 -#: ../../Zotlabs/Module/Profile_photo.php:351 +#: ../../Zotlabs/Module/Profile_photo.php:335 +#: ../../Zotlabs/Module/Profile_photo.php:348 #: ../../Zotlabs/Module/Common.php:38 ../../Zotlabs/Module/Editwebpage.php:68 #: ../../Zotlabs/Module/Editwebpage.php:89 #: ../../Zotlabs/Module/Editwebpage.php:107 #: ../../Zotlabs/Module/Editwebpage.php:121 ../../Zotlabs/Module/Page.php:34 #: ../../Zotlabs/Module/Page.php:133 ../../Zotlabs/Module/Layouts.php:71 #: ../../Zotlabs/Module/Layouts.php:78 ../../Zotlabs/Module/Layouts.php:89 -#: ../../Zotlabs/Module/Bookmarks.php:70 ../../Zotlabs/Module/Defperms.php:182 +#: ../../Zotlabs/Module/Bookmarks.php:70 ../../Zotlabs/Module/Defperms.php:181 #: ../../Zotlabs/Module/Api.php:24 ../../Zotlabs/Module/Article_edit.php:51 #: ../../Zotlabs/Module/Suggest.php:32 ../../Zotlabs/Module/Filestorage.php:20 #: ../../Zotlabs/Module/Filestorage.php:78 @@ -265,17 +284,17 @@ msgstr "никогда" #: ../../Zotlabs/Module/Vote.php:19 ../../Zotlabs/Module/Locs.php:98 #: ../../Zotlabs/Module/Invite.php:51 ../../Zotlabs/Module/Invite.php:302 #: ../../Zotlabs/Module/Cover_photo.php:341 -#: ../../Zotlabs/Module/Cover_photo.php:354 ../../Zotlabs/Module/Network.php:19 -#: ../../Zotlabs/Module/Like.php:242 ../../Zotlabs/Module/New_channel.php:105 +#: ../../Zotlabs/Module/Cover_photo.php:354 ../../Zotlabs/Module/Network.php:18 +#: ../../Zotlabs/Module/Like.php:248 ../../Zotlabs/Module/New_channel.php:105 #: ../../Zotlabs/Module/New_channel.php:130 ../../Zotlabs/Module/Cards.php:84 #: ../../Zotlabs/Module/Menu.php:130 ../../Zotlabs/Module/Menu.php:141 #: ../../Zotlabs/Module/Editlayout.php:67 #: ../../Zotlabs/Module/Editlayout.php:90 ../../Zotlabs/Module/Thing.php:282 #: ../../Zotlabs/Module/Thing.php:302 ../../Zotlabs/Module/Thing.php:343 #: ../../Zotlabs/Module/Webpages.php:131 ../../Zotlabs/Module/Moderate.php:15 -#: ../../Zotlabs/Module/Group.php:15 ../../Zotlabs/Module/Group.php:31 +#: ../../Zotlabs/Module/Group.php:14 ../../Zotlabs/Module/Group.php:30 #: ../../Zotlabs/Module/Profile.php:99 ../../Zotlabs/Module/Profile.php:114 -#: ../../Zotlabs/Module/Connedit.php:394 ../../Zotlabs/Module/Editpost.php:17 +#: ../../Zotlabs/Module/Connedit.php:299 ../../Zotlabs/Module/Editpost.php:17 #: ../../Zotlabs/Module/Manage.php:10 ../../Zotlabs/Module/Articles.php:87 #: ../../Zotlabs/Module/Achievements.php:34 #: ../../Zotlabs/Module/Display.php:424 ../../Zotlabs/Module/Setup.php:208 @@ -292,7 +311,7 @@ msgstr "никогда" #: ../../Zotlabs/Module/Settings.php:58 ../../Zotlabs/Module/Wiki.php:57 #: ../../Zotlabs/Module/Wiki.php:282 ../../Zotlabs/Module/Wiki.php:425 #: ../../Zotlabs/Lib/Chatroom.php:135 ../../Zotlabs/Web/WebServer.php:116 -#: ../../include/photos.php:30 ../../include/items.php:3749 +#: ../../include/photos.php:30 ../../include/items.php:3881 #: ../../include/attach.php:156 ../../include/attach.php:205 #: ../../include/attach.php:278 ../../include/attach.php:329 #: ../../include/attach.php:424 ../../include/attach.php:438 @@ -310,7 +329,7 @@ msgstr "Доступ запрещен." #: ../../Zotlabs/Module/Admin/Addons.php:260 ../../Zotlabs/Module/Admin.php:61 #: ../../Zotlabs/Module/Filestorage.php:29 ../../Zotlabs/Module/Thing.php:96 #: ../../Zotlabs/Module/Display.php:53 ../../Zotlabs/Module/Display.php:428 -#: ../../include/items.php:3672 +#: ../../include/items.php:3804 #: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:291 #: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:292 msgid "Item not found." @@ -380,63 +399,73 @@ msgstr "Невозможно найти ваш сервер" msgid "Post successful." msgstr "Успешно опубликовано." -#: ../../Zotlabs/Module/Uexport.php:71 ../../Zotlabs/Module/Uexport.php:72 +#: ../../Zotlabs/Module/Uexport.php:108 +msgid "No content available for year" +msgstr "Содержимое для года недоступно" + +#: ../../Zotlabs/Module/Uexport.php:171 msgid "Export Channel" msgstr "Экспорт канала" -#: ../../Zotlabs/Module/Uexport.php:73 +#: ../../Zotlabs/Module/Uexport.php:173 +msgid "Export channel" +msgstr "Экспортировать канал" + +#: ../../Zotlabs/Module/Uexport.php:174 msgid "" -"Export your basic channel information to a file. This acts as a backup of " -"your connections, permissions, profile and basic data, which can be used to " -"import your data to a new server hub, but does not contain your content." -msgstr "Экспортировать основную информацию из канала в файл. Служит в качестве резервной копии ваших контактов, основных данных и профиля, однако не включает содержимое. Может быть использовано для импорта ваши данных на новый сервер." +"This will export your identity and social graph into a file which can be " +"used to import your channel to a new hub." +msgstr "Экспортировать ваши данные и социальный граф в файл, который можно использовать для импорта вашего канала на новом хабе." -#: ../../Zotlabs/Module/Uexport.php:74 -msgid "Export Content" +#: ../../Zotlabs/Module/Uexport.php:177 +msgid "Export content" msgstr "Экспортировать содержимое" -#: ../../Zotlabs/Module/Uexport.php:75 +#: ../../Zotlabs/Module/Uexport.php:178 msgid "" -"Export your channel information and recent content to a JSON backup that can " -"be restored or imported to another server hub. This backs up all of your " -"connections, permissions, profile data and several months of posts. This " -"file may be VERY large. Please be patient - it may take several minutes for " -"this download to begin." -msgstr "Экспортировать информацию из вашего канала и его содержимое в резервную копию в формате JSON которая может быть использована для восстановления или импорта на другом сервере. Сохраняет все ваши контакты, разрешения, данные профиля и публикации за несколько месяцев. Файл может иметь очень большой размер. Пожалуйста, будьте терпеливы и подождите несколько минут пока не начнётся загрузка." +"This will export your posts, direct messages, articles and cards per month " +"stored into a zip file per year. Months with no posts will be dismissed." +msgstr "Экспортировать ваши публикации, личные сообщения, статьи и карточки за месяц, хранящиеся в zip-файле за год. Месяцы без сообщений будут отклонены." -#: ../../Zotlabs/Module/Uexport.php:77 -msgid "Export your posts from a given year." -msgstr "Экспортировать ваши публикации за данный год." +#: ../../Zotlabs/Module/Uexport.php:180 +msgid "Export wikis" +msgstr "Экспортировать wiki" -#: ../../Zotlabs/Module/Uexport.php:79 -msgid "" -"You may also export your posts and conversations for a particular year or " -"month. Adjust the date in your browser location bar to select other dates. " -"If the export fails (possibly due to memory exhaustion on your server hub), " -"please try again selecting a more limited date range." -msgstr "Вы также можете экспортировать ваши публикации и беседы за определённый месяц или год. Выберите дату в панели местоположения в браузере. Если экспорт будет неудачным (это возможно, например, из-за исчерпания памяти на сервере), повторите попытку, выбрав меньший диапазон дат." +#: ../../Zotlabs/Module/Uexport.php:181 +msgid "This will export your wikis and wiki pages." +msgstr "Экспортировать ваши wiki и их страницы." -#: ../../Zotlabs/Module/Uexport.php:80 -#, php-format -msgid "" -"To select all posts for a given year, such as this year, visit %2$s" -msgstr "Для выбора всех публикаций заданного года, например текущего, посетите %2$s" +#: ../../Zotlabs/Module/Uexport.php:183 +msgid "Export webpages" +msgstr "Экспортировать веб-страницы" -#: ../../Zotlabs/Module/Uexport.php:81 -#, php-format +#: ../../Zotlabs/Module/Uexport.php:184 +msgid "This will export your webpages and menus." +msgstr "Экспортировать ваши веб-страницы и меню." + +#: ../../Zotlabs/Module/Uexport.php:186 +msgid "Export channel calendar" +msgstr "Экспортировать календарь канала" + +#: ../../Zotlabs/Module/Uexport.php:187 msgid "" -"To select all posts for a given month, such as January of this year, visit " -"%2$s" -msgstr "Для выбора всех публикаций заданного месяца, например за январь сего года, посетите %2$s" +"This will export your channel calendar events and associated items. CalDAV " +"calendars are not included." +msgstr "Экспортировать события календаря вашего канала и связанные элементы, за исключением календарей CalDAV." -#: ../../Zotlabs/Module/Uexport.php:82 +#: ../../Zotlabs/Module/Uexport.php:189 +msgid "Export chatrooms" +msgstr "Экспортировать комнаты чатов" + +#: ../../Zotlabs/Module/Uexport.php:190 +msgid "This will export your chatrooms. Chat history is dismissed." +msgstr "Эксортировать ваши комнаты чатов. История не сохраняется." + +#: ../../Zotlabs/Module/Uexport.php:192 #, php-format msgid "" -"These content files may be imported or restored by visiting " -"%2$s on any site containing your channel. For best results please import " -"or restore these in date order (oldest first)." -msgstr "Данные файлы с содержимым могут быть импортированы и восстановлены на любом содержащем ваш канал сайте. Посетите %2$s. Для лучших результатов пожалуйста производите импорт и восстановление в порядке датировки (старые сначала)." +"This export can be imported or restored by visiting %2$s on any site containing your channel." +msgstr "Этот файл можно импортировать или восстановить, посетив % 2 $ s на любом сайте, где есть ваш канал." #: ../../Zotlabs/Module/Chatsvc.php:131 msgid "Away" @@ -461,7 +490,7 @@ msgstr "Канал не найден." #: ../../Zotlabs/Module/Block.php:77 ../../Zotlabs/Module/Page.php:136 #: ../../Zotlabs/Module/Display.php:142 ../../Zotlabs/Module/Display.php:159 #: ../../Zotlabs/Module/Display.php:179 ../../Zotlabs/Module/Display.php:185 -#: ../../Zotlabs/Lib/NativeWikiPage.php:533 ../../Zotlabs/Web/Router.php:186 +#: ../../Zotlabs/Lib/NativeWikiPage.php:539 ../../Zotlabs/Web/Router.php:186 #: ../../include/help.php:133 msgid "Page not found." msgstr "Страница не найдена." @@ -471,37 +500,37 @@ msgstr "Страница не найдена." msgid "You must be logged in to see this page." msgstr "Вы должны авторизоваться, чтобы увидеть эту страницу." -#: ../../Zotlabs/Module/Channel.php:136 ../../Zotlabs/Module/Profile.php:62 +#: ../../Zotlabs/Module/Channel.php:139 ../../Zotlabs/Module/Profile.php:62 #: ../../Zotlabs/Module/Hcard.php:37 msgid "Posts and comments" msgstr "Публикации и комментарии" -#: ../../Zotlabs/Module/Channel.php:143 ../../Zotlabs/Module/Profile.php:69 +#: ../../Zotlabs/Module/Channel.php:146 ../../Zotlabs/Module/Profile.php:69 #: ../../Zotlabs/Module/Hcard.php:44 msgid "Only posts" msgstr "Только публикации" -#: ../../Zotlabs/Module/Channel.php:156 ../../Zotlabs/Module/Channel.php:178 +#: ../../Zotlabs/Module/Channel.php:159 ../../Zotlabs/Module/Channel.php:181 #: ../../Zotlabs/Module/Pubstream.php:47 ../../Zotlabs/Module/Oep.php:83 #: ../../Zotlabs/Module/Display.php:47 ../../Zotlabs/Module/Hq.php:39 msgid "Malformed message id." msgstr "Неверный идентификатор сообщения." -#: ../../Zotlabs/Module/Channel.php:214 +#: ../../Zotlabs/Module/Channel.php:217 msgid "Insufficient permissions. Request redirected to profile page." msgstr "Недостаточно прав. Запрос перенаправлен на страницу профиля." -#: ../../Zotlabs/Module/Channel.php:229 ../../Zotlabs/Module/Network.php:168 +#: ../../Zotlabs/Module/Channel.php:232 ../../Zotlabs/Module/Network.php:167 msgid "Search Results For:" msgstr "Результаты поиска для:" -#: ../../Zotlabs/Module/Channel.php:264 ../../Zotlabs/Module/Network.php:209 +#: ../../Zotlabs/Module/Channel.php:267 ../../Zotlabs/Module/Network.php:208 #: ../../Zotlabs/Module/Pubstream.php:90 ../../Zotlabs/Module/Display.php:87 #: ../../Zotlabs/Module/Hq.php:114 msgid "Reset form" msgstr "Очистить форму" -#: ../../Zotlabs/Module/Channel.php:491 ../../Zotlabs/Module/Display.php:358 +#: ../../Zotlabs/Module/Channel.php:494 ../../Zotlabs/Module/Display.php:358 msgid "" "You must enable javascript for your browser to be able to view this content." msgstr "Для просмотра этого содержимого в вашем браузере должен быть включён JavaScript" @@ -524,17 +553,17 @@ msgstr "Используйте стрелки для перемещения пр msgid "Use arrows to move the corresponding app up or down in the app tray" msgstr "Используйте стрелки для перемещения приложения вверх или вниз в лотке" -#: ../../Zotlabs/Module/Register.php:95 ../../include/channel.php:211 +#: ../../Zotlabs/Module/Register.php:95 ../../include/channel.php:213 msgid "Nickname is required." msgstr "Требуется псевдоним." #: ../../Zotlabs/Module/Register.php:100 ../../Zotlabs/Module/Changeaddr.php:46 -#: ../../include/channel.php:225 ../../include/channel.php:657 +#: ../../include/channel.php:227 ../../include/channel.php:659 msgid "Reserved nickname. Please choose another." msgstr "Зарезервированый псевдоним. Пожалуйста, выберите другой." #: ../../Zotlabs/Module/Register.php:105 ../../Zotlabs/Module/Changeaddr.php:51 -#: ../../include/channel.php:230 ../../include/channel.php:662 +#: ../../include/channel.php:232 ../../include/channel.php:664 msgid "" "Nickname has unsupported characters or is already being used on this site." msgstr "Псевдоним имеет недопустимые символы или уже используется на этом сайте." @@ -631,9 +660,9 @@ msgstr "Мой возраст превышает %s лет и я принима msgid "Your email address" msgstr "Ваш адрес электронной почты" -#: ../../Zotlabs/Module/Register.php:498 ../../Zotlabs/Module/Appman.php:147 -#: ../../Zotlabs/Module/Appman.php:148 ../../Zotlabs/Module/Profiles.php:747 -#: ../../Zotlabs/Module/Profiles.php:751 ../../include/datetime.php:211 +#: ../../Zotlabs/Module/Register.php:498 ../../Zotlabs/Module/Appman.php:209 +#: ../../Zotlabs/Module/Appman.php:210 ../../Zotlabs/Module/Profiles.php:787 +#: ../../Zotlabs/Module/Profiles.php:791 ../../include/datetime.php:211 #: ../../include/js_strings.php:123 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:334 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:358 @@ -711,11 +740,11 @@ msgstr "Альбом не найден." msgid "Delete Album" msgstr "Удалить альбом" -#: ../../Zotlabs/Module/Photos.php:177 ../../Zotlabs/Module/Photos.php:1063 +#: ../../Zotlabs/Module/Photos.php:177 ../../Zotlabs/Module/Photos.php:1065 msgid "Delete Photo" msgstr "Удалить фотографию" -#: ../../Zotlabs/Module/Photos.php:523 ../../Zotlabs/Module/Search.php:21 +#: ../../Zotlabs/Module/Photos.php:523 ../../Zotlabs/Module/Search.php:22 #: ../../Zotlabs/Module/Display.php:28 #: ../../Zotlabs/Module/Viewconnections.php:23 #: ../../Zotlabs/Module/Directory.php:72 ../../Zotlabs/Module/Directory.php:77 @@ -756,10 +785,10 @@ msgstr "или выберите существующий альбом (двой msgid "Create a status post for this upload" msgstr "Сделать публикацию о статусе для этой загрузки" -#: ../../Zotlabs/Module/Photos.php:678 ../../Zotlabs/Module/Photos.php:1048 +#: ../../Zotlabs/Module/Photos.php:678 ../../Zotlabs/Module/Photos.php:1050 #: ../../Zotlabs/Module/Card_edit.php:118 #: ../../Zotlabs/Module/Article_edit.php:116 -#: ../../Zotlabs/Module/Editblock.php:129 ../../include/conversation.php:1481 +#: ../../Zotlabs/Module/Editblock.php:129 ../../include/conversation.php:1495 #: ../../extend/addon/hzaddons/hsse/hsse.php:221 msgid "Title (optional)" msgstr "Заголовок (необязательно)" @@ -768,16 +797,16 @@ msgstr "Заголовок (необязательно)" msgid "Description (optional)" msgstr "Описание (необязательно)" -#: ../../Zotlabs/Module/Photos.php:682 ../../Zotlabs/Module/Photos.php:1051 +#: ../../Zotlabs/Module/Photos.php:682 ../../Zotlabs/Module/Photos.php:1053 #: ../../Zotlabs/Module/Filestorage.php:195 ../../Zotlabs/Module/Chat.php:239 #: ../../Zotlabs/Module/Thing.php:321 ../../Zotlabs/Module/Thing.php:374 -#: ../../Zotlabs/Module/Connedit.php:675 ../../include/acl_selectors.php:154 +#: ../../include/acl_selectors.php:154 #: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:261 msgid "Permissions" msgstr "Разрешения" #: ../../Zotlabs/Module/Photos.php:692 -#: ../../Zotlabs/Module/Profile_photo.php:500 +#: ../../Zotlabs/Module/Profile_photo.php:497 #: ../../Zotlabs/Module/Embedphotos.php:189 #: ../../Zotlabs/Module/Cover_photo.php:423 #: ../../Zotlabs/Storage/Browser.php:540 ../../Zotlabs/Widget/Cdav.php:146 @@ -786,119 +815,119 @@ msgstr "Разрешения" msgid "Upload" msgstr "Загрузка" -#: ../../Zotlabs/Module/Photos.php:765 +#: ../../Zotlabs/Module/Photos.php:767 msgid "Show Newest First" msgstr "Показать новые первыми" -#: ../../Zotlabs/Module/Photos.php:767 +#: ../../Zotlabs/Module/Photos.php:769 msgid "Show Oldest First" msgstr "Показать старые первыми" -#: ../../Zotlabs/Module/Photos.php:791 ../../Zotlabs/Module/Photos.php:1335 +#: ../../Zotlabs/Module/Photos.php:793 ../../Zotlabs/Module/Photos.php:1337 #: ../../Zotlabs/Module/Embedphotos.php:171 ../../Zotlabs/Widget/Album.php:78 #: ../../Zotlabs/Widget/Portfolio.php:87 msgid "View Photo" msgstr "Посмотреть фотографию" -#: ../../Zotlabs/Module/Photos.php:797 ../../Zotlabs/Module/Photos.php:1257 -#: ../../Zotlabs/Module/Embedphotos.php:177 ../../Zotlabs/Lib/Activity.php:1605 -#: ../../Zotlabs/Lib/Apps.php:1164 ../../Zotlabs/Lib/Apps.php:1248 +#: ../../Zotlabs/Module/Photos.php:799 ../../Zotlabs/Module/Photos.php:1259 +#: ../../Zotlabs/Module/Embedphotos.php:177 ../../Zotlabs/Lib/Activity.php:1656 +#: ../../Zotlabs/Lib/Apps.php:1148 ../../Zotlabs/Lib/Apps.php:1232 #: ../../Zotlabs/Widget/Album.php:84 ../../Zotlabs/Widget/Portfolio.php:95 #: ../../Zotlabs/Widget/Pinned.php:268 ../../include/cdav.php:158 #: ../../include/cdav.php:159 ../../include/cdav.php:167 -#: ../../include/conversation.php:1217 +#: ../../include/conversation.php:1231 msgid "Unknown" msgstr "Неизвестный" -#: ../../Zotlabs/Module/Photos.php:822 ../../Zotlabs/Module/Embedphotos.php:187 +#: ../../Zotlabs/Module/Photos.php:824 ../../Zotlabs/Module/Embedphotos.php:187 #: ../../Zotlabs/Widget/Album.php:95 ../../Zotlabs/Widget/Portfolio.php:108 msgid "Edit Album" msgstr "Редактировать Фотоальбом" -#: ../../Zotlabs/Module/Photos.php:824 ../../Zotlabs/Module/Photos.php:1366 +#: ../../Zotlabs/Module/Photos.php:826 ../../Zotlabs/Module/Photos.php:1368 msgid "Add Photos" msgstr "Добавить фотографии" -#: ../../Zotlabs/Module/Photos.php:872 +#: ../../Zotlabs/Module/Photos.php:874 msgid "Permission denied. Access to this item may be restricted." msgstr "Доступ запрещен. Доступ к этому элементу может быть ограничен." -#: ../../Zotlabs/Module/Photos.php:874 +#: ../../Zotlabs/Module/Photos.php:876 msgid "Photo not available" msgstr "Фотография не доступна" -#: ../../Zotlabs/Module/Photos.php:932 +#: ../../Zotlabs/Module/Photos.php:934 msgid "Use as profile photo" msgstr "Использовать в качестве фотографии профиля" -#: ../../Zotlabs/Module/Photos.php:933 +#: ../../Zotlabs/Module/Photos.php:935 msgid "Use as cover photo" msgstr "Использовать в качестве фотографии обложки" -#: ../../Zotlabs/Module/Photos.php:940 +#: ../../Zotlabs/Module/Photos.php:942 msgid "Private Photo" msgstr "Личная фотография" -#: ../../Zotlabs/Module/Photos.php:951 ../../Zotlabs/Module/Cdav.php:1034 +#: ../../Zotlabs/Module/Photos.php:953 ../../Zotlabs/Module/Cdav.php:1034 #: ../../Zotlabs/Module/Cal.php:203 msgid "Previous" msgstr "Предыдущая" -#: ../../Zotlabs/Module/Photos.php:955 +#: ../../Zotlabs/Module/Photos.php:957 msgid "View Full Size" msgstr "Посмотреть в полный размер" -#: ../../Zotlabs/Module/Photos.php:960 ../../Zotlabs/Module/Cdav.php:1035 +#: ../../Zotlabs/Module/Photos.php:962 ../../Zotlabs/Module/Cdav.php:1035 #: ../../Zotlabs/Module/Cal.php:204 ../../Zotlabs/Module/Setup.php:262 msgid "Next" msgstr "Следующая" -#: ../../Zotlabs/Module/Photos.php:1000 +#: ../../Zotlabs/Module/Photos.php:1002 #: ../../Zotlabs/Module/Admin/Addons.php:459 ../../Zotlabs/Module/Tagrm.php:137 -#: ../../Zotlabs/Module/Profile_photo.php:501 +#: ../../Zotlabs/Module/Profile_photo.php:498 #: ../../Zotlabs/Module/Cover_photo.php:424 #: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:90 msgid "Remove" msgstr "Удалить" -#: ../../Zotlabs/Module/Photos.php:1037 +#: ../../Zotlabs/Module/Photos.php:1039 msgid "Edit photo" msgstr "Редактировать фотографию" -#: ../../Zotlabs/Module/Photos.php:1039 +#: ../../Zotlabs/Module/Photos.php:1041 msgid "Rotate CW (right)" msgstr "Повернуть CW (направо)" -#: ../../Zotlabs/Module/Photos.php:1040 +#: ../../Zotlabs/Module/Photos.php:1042 msgid "Rotate CCW (left)" msgstr "Повернуть CCW (налево)" -#: ../../Zotlabs/Module/Photos.php:1043 +#: ../../Zotlabs/Module/Photos.php:1045 msgid "Move photo to album" msgstr "Переместить фотографию в альбом" -#: ../../Zotlabs/Module/Photos.php:1044 +#: ../../Zotlabs/Module/Photos.php:1046 msgid "Enter a new album name" msgstr "Введите новое название альбома" -#: ../../Zotlabs/Module/Photos.php:1045 +#: ../../Zotlabs/Module/Photos.php:1047 msgid "or select an existing one (doubleclick)" msgstr "или выбрать существующую (двойной щелчок)" -#: ../../Zotlabs/Module/Photos.php:1050 +#: ../../Zotlabs/Module/Photos.php:1052 msgid "Add a Tag" msgstr "Добавить тег" -#: ../../Zotlabs/Module/Photos.php:1058 +#: ../../Zotlabs/Module/Photos.php:1060 msgid "Example: @bob, @Barbara_Jensen, @jim@example.com" msgstr "Пример: @bob, @Barbara_Jensen, @jim@example.com" -#: ../../Zotlabs/Module/Photos.php:1061 +#: ../../Zotlabs/Module/Photos.php:1063 msgid "Flag as adult in album view" msgstr "Пометить как альбом \"для взрослых\"" -#: ../../Zotlabs/Module/Photos.php:1062 ../../Zotlabs/Module/Photos.php:1102 -#: ../../Zotlabs/Module/Photos.php:1218 ../../Zotlabs/Module/Appman.php:159 +#: ../../Zotlabs/Module/Photos.php:1064 ../../Zotlabs/Module/Photos.php:1104 +#: ../../Zotlabs/Module/Photos.php:1220 ../../Zotlabs/Module/Appman.php:221 #: ../../Zotlabs/Module/Admin/Account_edit.php:73 #: ../../Zotlabs/Module/Admin/Accounts.php:309 #: ../../Zotlabs/Module/Admin/Themes.php:158 @@ -910,13 +939,14 @@ msgstr "Пометить как альбом \"для взрослых\"" #: ../../Zotlabs/Module/Admin/Security.php:120 #: ../../Zotlabs/Module/Admin/Logs.php:84 ../../Zotlabs/Module/Sources.php:123 #: ../../Zotlabs/Module/Sources.php:160 ../../Zotlabs/Module/Poke.php:215 -#: ../../Zotlabs/Module/Profiles.php:725 ../../Zotlabs/Module/Oauth.php:109 +#: ../../Zotlabs/Module/Profiles.php:765 ../../Zotlabs/Module/Oauth.php:109 #: ../../Zotlabs/Module/Connect.php:107 -#: ../../Zotlabs/Module/Import_items.php:129 -#: ../../Zotlabs/Module/Regate.php:387 ../../Zotlabs/Module/Defperms.php:264 +#: ../../Zotlabs/Module/Import_items.php:125 +#: ../../Zotlabs/Module/Regate.php:407 ../../Zotlabs/Module/Defperms.php:263 #: ../../Zotlabs/Module/Xchan.php:15 ../../Zotlabs/Module/Filestorage.php:208 -#: ../../Zotlabs/Module/Permcats.php:127 ../../Zotlabs/Module/Pdledit.php:106 +#: ../../Zotlabs/Module/Permcats.php:242 ../../Zotlabs/Module/Pdledit.php:106 #: ../../Zotlabs/Module/Chat.php:207 ../../Zotlabs/Module/Chat.php:246 +#: ../../Zotlabs/Module/Settings/Privacy.php:110 #: ../../Zotlabs/Module/Settings/Directory.php:42 #: ../../Zotlabs/Module/Settings/Account.php:107 #: ../../Zotlabs/Module/Settings/Calendar.php:42 @@ -930,19 +960,21 @@ msgstr "Пометить как альбом \"для взрослых\"" #: ../../Zotlabs/Module/Settings/Events.php:42 #: ../../Zotlabs/Module/Settings/Channel_home.php:91 #: ../../Zotlabs/Module/Settings/Profiles.php:52 -#: ../../Zotlabs/Module/Settings/Channel.php:499 +#: ../../Zotlabs/Module/Settings/Channel.php:224 #: ../../Zotlabs/Module/Settings/Connections.php:42 -#: ../../Zotlabs/Module/Locs.php:125 ../../Zotlabs/Module/Invite.php:549 -#: ../../Zotlabs/Module/Affinity.php:84 ../../Zotlabs/Module/Pconfig.php:116 -#: ../../Zotlabs/Module/Thing.php:328 ../../Zotlabs/Module/Thing.php:381 +#: ../../Zotlabs/Module/Contactedit.php:429 +#: ../../Zotlabs/Module/Contactedit.php:455 ../../Zotlabs/Module/Locs.php:125 +#: ../../Zotlabs/Module/Invite.php:550 ../../Zotlabs/Module/Affinity.php:84 +#: ../../Zotlabs/Module/Pconfig.php:116 ../../Zotlabs/Module/Thing.php:328 +#: ../../Zotlabs/Module/Thing.php:381 #: ../../Zotlabs/Module/Email_validation.php:40 -#: ../../Zotlabs/Module/Import.php:602 ../../Zotlabs/Module/Group.php:149 -#: ../../Zotlabs/Module/Group.php:165 ../../Zotlabs/Module/Connedit.php:889 +#: ../../Zotlabs/Module/Import.php:611 ../../Zotlabs/Module/Group.php:166 +#: ../../Zotlabs/Module/Group.php:185 ../../Zotlabs/Module/Connedit.php:714 #: ../../Zotlabs/Module/Editpost.php:86 ../../Zotlabs/Module/Setup.php:306 #: ../../Zotlabs/Module/Setup.php:346 ../../Zotlabs/Module/Mitem.php:259 #: ../../Zotlabs/Module/Mood.php:156 ../../Zotlabs/Module/Oauth2.php:114 -#: ../../Zotlabs/Module/Wiki.php:212 ../../Zotlabs/Module/Tokens.php:186 -#: ../../Zotlabs/Storage/Browser.php:382 ../../Zotlabs/Lib/ThreadItem.php:827 +#: ../../Zotlabs/Module/Wiki.php:212 ../../Zotlabs/Module/Tokens.php:293 +#: ../../Zotlabs/Storage/Browser.php:382 ../../Zotlabs/Lib/ThreadItem.php:850 #: ../../Zotlabs/Widget/Eventstools.php:16 #: ../../Zotlabs/Widget/Wiki_pages.php:42 #: ../../Zotlabs/Widget/Wiki_pages.php:99 ../../include/js_strings.php:22 @@ -957,7 +989,7 @@ msgstr "Пометить как альбом \"для взрослых\"" #: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:248 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:312 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:412 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:644 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:645 #: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:410 #: ../../extend/addon/hzaddons/cart/cart.php:1376 #: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:107 @@ -1004,97 +1036,97 @@ msgstr "Пометить как альбом \"для взрослых\"" msgid "Submit" msgstr "Отправить" -#: ../../Zotlabs/Module/Photos.php:1080 ../../Zotlabs/Lib/ThreadItem.php:318 +#: ../../Zotlabs/Module/Photos.php:1082 ../../Zotlabs/Lib/ThreadItem.php:341 msgid "I like this (toggle)" msgstr "мне это нравится (переключение)" -#: ../../Zotlabs/Module/Photos.php:1081 ../../Zotlabs/Lib/ThreadItem.php:319 +#: ../../Zotlabs/Module/Photos.php:1083 ../../Zotlabs/Lib/ThreadItem.php:342 msgid "I don't like this (toggle)" msgstr "мне это не нравится (переключение)" -#: ../../Zotlabs/Module/Photos.php:1082 ../../Zotlabs/Module/Layouts.php:194 +#: ../../Zotlabs/Module/Photos.php:1084 ../../Zotlabs/Module/Layouts.php:194 #: ../../Zotlabs/Module/Blocks.php:161 ../../Zotlabs/Module/Webpages.php:253 #: ../../Zotlabs/Module/Wiki.php:298 ../../Zotlabs/Widget/Cdav.php:136 -#: ../../include/conversation.php:1441 +#: ../../include/conversation.php:1455 #: ../../extend/addon/hzaddons/hsse/hsse.php:186 msgid "Share" msgstr "Поделиться" -#: ../../Zotlabs/Module/Photos.php:1083 ../../Zotlabs/Lib/ThreadItem.php:503 +#: ../../Zotlabs/Module/Photos.php:1085 ../../Zotlabs/Lib/ThreadItem.php:526 #: ../../include/conversation.php:838 msgid "Please wait" msgstr "Подождите пожалуйста" -#: ../../Zotlabs/Module/Photos.php:1099 ../../Zotlabs/Module/Photos.php:1215 -#: ../../Zotlabs/Lib/ThreadItem.php:824 +#: ../../Zotlabs/Module/Photos.php:1101 ../../Zotlabs/Module/Photos.php:1217 +#: ../../Zotlabs/Lib/ThreadItem.php:847 msgid "This is you" msgstr "Это вы" -#: ../../Zotlabs/Module/Photos.php:1101 ../../Zotlabs/Module/Photos.php:1217 -#: ../../Zotlabs/Lib/ThreadItem.php:826 ../../include/js_strings.php:6 +#: ../../Zotlabs/Module/Photos.php:1103 ../../Zotlabs/Module/Photos.php:1219 +#: ../../Zotlabs/Lib/ThreadItem.php:849 ../../include/js_strings.php:6 msgid "Comment" msgstr "Комментарий" -#: ../../Zotlabs/Module/Photos.php:1103 ../../Zotlabs/Module/Webpages.php:259 -#: ../../Zotlabs/Lib/ThreadItem.php:837 ../../include/conversation.php:1408 +#: ../../Zotlabs/Module/Photos.php:1105 ../../Zotlabs/Module/Webpages.php:259 +#: ../../Zotlabs/Lib/ThreadItem.php:860 ../../include/conversation.php:1422 #: ../../extend/addon/hzaddons/hsse/hsse.php:153 msgid "Preview" msgstr "Предварительный просмотр" -#: ../../Zotlabs/Module/Photos.php:1117 ../../include/conversation.php:652 +#: ../../Zotlabs/Module/Photos.php:1119 ../../include/conversation.php:652 msgctxt "title" msgid "Likes" msgstr "Нравится" -#: ../../Zotlabs/Module/Photos.php:1117 ../../include/conversation.php:653 +#: ../../Zotlabs/Module/Photos.php:1119 ../../include/conversation.php:653 msgctxt "title" msgid "Dislikes" msgstr "Не нравится" -#: ../../Zotlabs/Module/Photos.php:1118 ../../Zotlabs/Widget/Pinned.php:77 +#: ../../Zotlabs/Module/Photos.php:1120 ../../Zotlabs/Widget/Pinned.php:77 #: ../../include/conversation.php:654 msgctxt "title" msgid "Agree" msgstr "Согласен" -#: ../../Zotlabs/Module/Photos.php:1118 ../../Zotlabs/Widget/Pinned.php:78 +#: ../../Zotlabs/Module/Photos.php:1120 ../../Zotlabs/Widget/Pinned.php:78 #: ../../include/conversation.php:655 msgctxt "title" msgid "Disagree" msgstr "Не согласен" -#: ../../Zotlabs/Module/Photos.php:1118 ../../Zotlabs/Widget/Pinned.php:79 +#: ../../Zotlabs/Module/Photos.php:1120 ../../Zotlabs/Widget/Pinned.php:79 #: ../../include/conversation.php:656 msgctxt "title" msgid "Abstain" msgstr "Воздержался" -#: ../../Zotlabs/Module/Photos.php:1119 ../../Zotlabs/Widget/Pinned.php:66 +#: ../../Zotlabs/Module/Photos.php:1121 ../../Zotlabs/Widget/Pinned.php:66 #: ../../include/conversation.php:657 msgctxt "title" msgid "Attending" msgstr "Посещаю" -#: ../../Zotlabs/Module/Photos.php:1119 ../../Zotlabs/Widget/Pinned.php:67 +#: ../../Zotlabs/Module/Photos.php:1121 ../../Zotlabs/Widget/Pinned.php:67 #: ../../include/conversation.php:658 msgctxt "title" msgid "Not attending" msgstr "Не посещаю" -#: ../../Zotlabs/Module/Photos.php:1119 ../../Zotlabs/Widget/Pinned.php:68 +#: ../../Zotlabs/Module/Photos.php:1121 ../../Zotlabs/Widget/Pinned.php:68 #: ../../include/conversation.php:659 msgctxt "title" msgid "Might attend" msgstr "Возможно посещу" -#: ../../Zotlabs/Module/Photos.php:1136 ../../Zotlabs/Module/Photos.php:1148 -#: ../../Zotlabs/Lib/ThreadItem.php:239 ../../Zotlabs/Lib/ThreadItem.php:251 +#: ../../Zotlabs/Module/Photos.php:1138 ../../Zotlabs/Module/Photos.php:1150 +#: ../../Zotlabs/Lib/ThreadItem.php:262 ../../Zotlabs/Lib/ThreadItem.php:274 msgid "View all" msgstr "Просмотреть все" -#: ../../Zotlabs/Module/Photos.php:1140 ../../Zotlabs/Lib/ThreadItem.php:243 -#: ../../include/channel.php:1739 ../../include/taxonomy.php:670 -#: ../../include/conversation.php:1754 +#: ../../Zotlabs/Module/Photos.php:1142 ../../Zotlabs/Lib/ThreadItem.php:266 +#: ../../include/channel.php:1774 ../../include/taxonomy.php:670 +#: ../../include/conversation.php:1768 msgctxt "noun" msgid "Like" msgid_plural "Likes" @@ -1102,8 +1134,8 @@ msgstr[0] "Нравится" msgstr[1] "Нравится" msgstr[2] "Нравится" -#: ../../Zotlabs/Module/Photos.php:1145 ../../Zotlabs/Lib/ThreadItem.php:248 -#: ../../include/conversation.php:1757 +#: ../../Zotlabs/Module/Photos.php:1147 ../../Zotlabs/Lib/ThreadItem.php:271 +#: ../../include/conversation.php:1771 msgctxt "noun" msgid "Dislike" msgid_plural "Dislikes" @@ -1111,56 +1143,57 @@ msgstr[0] "Не нравится" msgstr[1] "Не нравится" msgstr[2] "Не нравится" -#: ../../Zotlabs/Module/Photos.php:1183 +#: ../../Zotlabs/Module/Photos.php:1185 #: ../../Zotlabs/Module/Admin/Accounts.php:320 #: ../../Zotlabs/Module/Admin/Profs.php:176 #: ../../Zotlabs/Module/Admin/Channels.php:149 -#: ../../Zotlabs/Module/Card_edit.php:130 ../../Zotlabs/Module/Profiles.php:802 -#: ../../Zotlabs/Module/Connections.php:329 ../../Zotlabs/Module/Cdav.php:1055 +#: ../../Zotlabs/Module/Card_edit.php:130 ../../Zotlabs/Module/Profiles.php:842 +#: ../../Zotlabs/Module/Connections.php:337 ../../Zotlabs/Module/Cdav.php:1055 #: ../../Zotlabs/Module/Cdav.php:1389 ../../Zotlabs/Module/Oauth.php:172 #: ../../Zotlabs/Module/Editwebpage.php:167 #: ../../Zotlabs/Module/Article_edit.php:128 -#: ../../Zotlabs/Module/Editblock.php:139 ../../Zotlabs/Module/Blocks.php:162 +#: ../../Zotlabs/Module/Permcats.php:246 ../../Zotlabs/Module/Editblock.php:139 +#: ../../Zotlabs/Module/Blocks.php:162 ../../Zotlabs/Module/Contactedit.php:660 #: ../../Zotlabs/Module/Editlayout.php:138 ../../Zotlabs/Module/Thing.php:269 -#: ../../Zotlabs/Module/Webpages.php:254 ../../Zotlabs/Module/Connedit.php:653 -#: ../../Zotlabs/Module/Connedit.php:925 ../../Zotlabs/Module/Oauth2.php:193 -#: ../../Zotlabs/Storage/Browser.php:384 ../../Zotlabs/Lib/ThreadItem.php:171 +#: ../../Zotlabs/Module/Webpages.php:254 ../../Zotlabs/Module/Connedit.php:540 +#: ../../Zotlabs/Module/Connedit.php:749 ../../Zotlabs/Module/Oauth2.php:193 +#: ../../Zotlabs/Storage/Browser.php:384 ../../Zotlabs/Lib/ThreadItem.php:194 #: ../../Zotlabs/Lib/Apps.php:598 ../../include/conversation.php:730 #: ../../include/conversation.php:784 msgid "Delete" msgstr "Удалить" -#: ../../Zotlabs/Module/Photos.php:1249 +#: ../../Zotlabs/Module/Photos.php:1251 msgid "Photo Tools" msgstr "Фото-Инструменты" -#: ../../Zotlabs/Module/Photos.php:1258 +#: ../../Zotlabs/Module/Photos.php:1260 msgid "In This Photo:" msgstr "На этой фотографии:" -#: ../../Zotlabs/Module/Photos.php:1263 +#: ../../Zotlabs/Module/Photos.php:1265 msgid "Map" msgstr "Карта" -#: ../../Zotlabs/Module/Photos.php:1271 ../../Zotlabs/Lib/ThreadItem.php:491 +#: ../../Zotlabs/Module/Photos.php:1273 ../../Zotlabs/Lib/ThreadItem.php:514 msgctxt "noun" msgid "Likes" msgstr "Нравится" -#: ../../Zotlabs/Module/Photos.php:1272 ../../Zotlabs/Lib/ThreadItem.php:492 +#: ../../Zotlabs/Module/Photos.php:1274 ../../Zotlabs/Lib/ThreadItem.php:515 msgctxt "noun" msgid "Dislikes" msgstr "Не нравится" -#: ../../Zotlabs/Module/Photos.php:1277 ../../Zotlabs/Storage/Browser.php:411 -#: ../../Zotlabs/Lib/ThreadItem.php:497 ../../Zotlabs/Widget/Pinned.php:158 +#: ../../Zotlabs/Module/Photos.php:1279 ../../Zotlabs/Storage/Browser.php:411 +#: ../../Zotlabs/Lib/ThreadItem.php:520 ../../Zotlabs/Widget/Pinned.php:158 #: ../../include/acl_selectors.php:156 #: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:233 msgid "Close" msgstr "Закрыть" -#: ../../Zotlabs/Module/Photos.php:1350 ../../Zotlabs/Module/Photos.php:1363 -#: ../../Zotlabs/Module/Photos.php:1364 ../../include/photos.php:715 +#: ../../Zotlabs/Module/Photos.php:1352 ../../Zotlabs/Module/Photos.php:1365 +#: ../../Zotlabs/Module/Photos.php:1366 ../../include/photos.php:723 msgid "Recent Photos" msgstr "Последние фотографии" @@ -1172,55 +1205,55 @@ msgstr "Приложение установлено." msgid "Malformed app." msgstr "Неработающее приложение." -#: ../../Zotlabs/Module/Appman.php:136 +#: ../../Zotlabs/Module/Appman.php:198 msgid "Embed code" msgstr "Встроить код" -#: ../../Zotlabs/Module/Appman.php:142 +#: ../../Zotlabs/Module/Appman.php:204 msgid "Edit App" msgstr "Редактировать приложение" -#: ../../Zotlabs/Module/Appman.php:142 +#: ../../Zotlabs/Module/Appman.php:204 msgid "Create App" msgstr "Создать приложение" -#: ../../Zotlabs/Module/Appman.php:147 +#: ../../Zotlabs/Module/Appman.php:209 msgid "Name of app" msgstr "Наименование приложения" -#: ../../Zotlabs/Module/Appman.php:148 +#: ../../Zotlabs/Module/Appman.php:210 msgid "Location (URL) of app" msgstr "Местоположение (URL) приложения" -#: ../../Zotlabs/Module/Appman.php:149 ../../Zotlabs/Module/Cdav.php:1013 +#: ../../Zotlabs/Module/Appman.php:211 ../../Zotlabs/Module/Cdav.php:1013 #: ../../Zotlabs/Module/Rbmark.php:100 #: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:260 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:656 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:657 #: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:173 msgid "Description" msgstr "Описание" -#: ../../Zotlabs/Module/Appman.php:150 +#: ../../Zotlabs/Module/Appman.php:212 msgid "Photo icon URL" msgstr "URL пиктограммы" -#: ../../Zotlabs/Module/Appman.php:150 +#: ../../Zotlabs/Module/Appman.php:212 msgid "80 x 80 pixels - optional" msgstr "80 x 80 пикселей - необязательно" -#: ../../Zotlabs/Module/Appman.php:151 +#: ../../Zotlabs/Module/Appman.php:213 msgid "Categories (optional, comma separated list)" msgstr "Категории (необязательно, список через запятую)" -#: ../../Zotlabs/Module/Appman.php:152 +#: ../../Zotlabs/Module/Appman.php:214 msgid "Version ID" msgstr "ID версии" -#: ../../Zotlabs/Module/Appman.php:153 +#: ../../Zotlabs/Module/Appman.php:215 msgid "Price of app" msgstr "Цена приложения" -#: ../../Zotlabs/Module/Appman.php:154 +#: ../../Zotlabs/Module/Appman.php:216 msgid "Location (URL) to purchase app" msgstr "Ссылка (URL) для покупки приложения" @@ -1342,7 +1375,7 @@ msgstr[2] "%s аккаунтов удалено" msgid "Account not found" msgstr "Аккаунт не найден" -#: ../../Zotlabs/Module/Admin/Accounts.php:184 ../../include/channel.php:2721 +#: ../../Zotlabs/Module/Admin/Accounts.php:184 ../../include/channel.php:2770 #, php-format msgid "Account '%s' deleted" msgstr "Аккаунт '%s' удален" @@ -1417,8 +1450,8 @@ msgstr "Дата запроса" #: ../../Zotlabs/Module/Admin/Accounts.php:316 #: ../../Zotlabs/Module/Admin/Accounts.php:330 -#: ../../Zotlabs/Module/Profiles.php:789 ../../Zotlabs/Module/Cdav.php:1376 -#: ../../Zotlabs/Module/Connedit.php:912 ../../include/network.php:1743 +#: ../../Zotlabs/Module/Profiles.php:829 ../../Zotlabs/Module/Cdav.php:1376 +#: ../../Zotlabs/Module/Connedit.php:736 ../../include/network.php:1743 #: ../../extend/addon/hzaddons/redred/Mod_Redred.php:69 #: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:55 #: ../../extend/addon/hzaddons/openid/MysqlProvider.php:56 @@ -1439,7 +1472,7 @@ msgid "No verified registrations available" msgstr "Нет доступных подтвержденных регистраций " #: ../../Zotlabs/Module/Admin/Accounts.php:318 -#: ../../Zotlabs/Module/Connections.php:343 ../../include/conversation.php:783 +#: ../../Zotlabs/Module/Connections.php:351 ../../include/conversation.php:783 msgid "Approve" msgstr "Утвердить" @@ -1449,12 +1482,14 @@ msgid "Deny" msgstr "Запретить" #: ../../Zotlabs/Module/Admin/Accounts.php:321 -#: ../../Zotlabs/Module/Connedit.php:621 +#: ../../Zotlabs/Module/Contactedit.php:632 +#: ../../Zotlabs/Module/Connedit.php:508 msgid "Block" msgstr "Блокировать" #: ../../Zotlabs/Module/Admin/Accounts.php:322 -#: ../../Zotlabs/Module/Connedit.php:621 +#: ../../Zotlabs/Module/Contactedit.php:632 +#: ../../Zotlabs/Module/Connedit.php:508 msgid "Unblock" msgstr "Разблокировать" @@ -1499,7 +1534,7 @@ msgid "" msgstr "Этот аккаунт {0} будет удалён!\n\nВсё что им было опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?" #: ../../Zotlabs/Module/Admin/Accounts.php:347 -#: ../../include/conversation.php:1126 +#: ../../include/conversation.php:1134 msgid "Message" msgstr "Сообщение" @@ -1566,7 +1601,7 @@ msgstr "Переключить" #: ../../Zotlabs/Module/Admin/Themes.php:125 #: ../../Zotlabs/Module/Admin/Addons.php:345 ../../Zotlabs/Lib/Apps.php:345 #: ../../Zotlabs/Widget/Newmember.php:53 -#: ../../Zotlabs/Widget/Settings_menu.php:61 ../../include/nav.php:103 +#: ../../Zotlabs/Widget/Settings_menu.php:66 ../../include/nav.php:101 msgid "Settings" msgstr "Настройки" @@ -1631,8 +1666,7 @@ msgstr "Дополнительная информация (необязател #: ../../Zotlabs/Module/Admin/Profs.php:114 ../../Zotlabs/Module/Filer.php:54 #: ../../Zotlabs/Module/Cards.php:111 ../../Zotlabs/Module/Rbmark.php:31 #: ../../Zotlabs/Module/Rbmark.php:103 ../../Zotlabs/Module/Articles.php:115 -#: ../../Zotlabs/Widget/Notes.php:23 ../../include/text.php:1146 -#: ../../include/text.php:1158 +#: ../../include/text.php:1143 ../../include/text.php:1155 #: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:116 msgid "Save" msgstr "Запомнить" @@ -1671,20 +1705,20 @@ msgstr "Настраиваемые поля" #: ../../Zotlabs/Module/Admin/Profs.php:175 #: ../../Zotlabs/Module/Card_edit.php:99 -#: ../../Zotlabs/Module/Connections.php:321 -#: ../../Zotlabs/Module/Connections.php:363 -#: ../../Zotlabs/Module/Connections.php:383 ../../Zotlabs/Module/Oauth.php:171 +#: ../../Zotlabs/Module/Connections.php:329 +#: ../../Zotlabs/Module/Connections.php:379 +#: ../../Zotlabs/Module/Connections.php:400 ../../Zotlabs/Module/Oauth.php:171 #: ../../Zotlabs/Module/Editwebpage.php:142 #: ../../Zotlabs/Module/Layouts.php:193 #: ../../Zotlabs/Module/Article_edit.php:97 #: ../../Zotlabs/Module/Editblock.php:114 ../../Zotlabs/Module/Blocks.php:160 #: ../../Zotlabs/Module/Menu.php:176 ../../Zotlabs/Module/Editlayout.php:114 #: ../../Zotlabs/Module/Thing.php:268 ../../Zotlabs/Module/Webpages.php:252 -#: ../../Zotlabs/Module/Group.php:251 ../../Zotlabs/Module/Oauth2.php:192 +#: ../../Zotlabs/Module/Group.php:271 ../../Zotlabs/Module/Oauth2.php:192 #: ../../Zotlabs/Module/Wiki.php:208 ../../Zotlabs/Module/Wiki.php:381 -#: ../../Zotlabs/Lib/ThreadItem.php:149 ../../Zotlabs/Lib/Apps.php:597 +#: ../../Zotlabs/Lib/ThreadItem.php:172 ../../Zotlabs/Lib/Apps.php:597 #: ../../Zotlabs/Widget/Cdav.php:138 ../../Zotlabs/Widget/Cdav.php:175 -#: ../../include/channel.php:1496 ../../include/channel.php:1500 +#: ../../include/channel.php:1530 ../../include/channel.php:1534 #: ../../include/menu.php:120 msgid "Edit" msgstr "Изменить" @@ -1783,9 +1817,9 @@ msgid "Install" msgstr "Установить" #: ../../Zotlabs/Module/Admin/Addons.php:427 -#: ../../Zotlabs/Module/Card_edit.php:132 ../../Zotlabs/Module/Profiles.php:803 +#: ../../Zotlabs/Module/Card_edit.php:132 ../../Zotlabs/Module/Profiles.php:843 #: ../../Zotlabs/Module/Tagrm.php:15 ../../Zotlabs/Module/Tagrm.php:138 -#: ../../Zotlabs/Module/Profile_photo.php:507 +#: ../../Zotlabs/Module/Profile_photo.php:504 #: ../../Zotlabs/Module/Cdav.php:1057 ../../Zotlabs/Module/Cdav.php:1390 #: ../../Zotlabs/Module/Oauth.php:110 ../../Zotlabs/Module/Oauth.php:136 #: ../../Zotlabs/Module/Editwebpage.php:169 @@ -1793,12 +1827,12 @@ msgstr "Установить" #: ../../Zotlabs/Module/Editblock.php:141 #: ../../Zotlabs/Module/Cover_photo.php:428 ../../Zotlabs/Module/Filer.php:56 #: ../../Zotlabs/Module/Editlayout.php:140 -#: ../../Zotlabs/Module/Connedit.php:926 ../../Zotlabs/Module/Editpost.php:111 +#: ../../Zotlabs/Module/Connedit.php:750 ../../Zotlabs/Module/Editpost.php:111 #: ../../Zotlabs/Module/Oauth2.php:115 ../../Zotlabs/Module/Oauth2.php:143 #: ../../Zotlabs/Module/Wiki.php:365 ../../Zotlabs/Module/Wiki.php:398 #: ../../Zotlabs/Module/Fbrowser.php:66 ../../Zotlabs/Module/Fbrowser.php:88 -#: ../../Zotlabs/Storage/Browser.php:383 ../../include/conversation.php:1464 -#: ../../include/conversation.php:1519 +#: ../../Zotlabs/Storage/Browser.php:383 ../../include/conversation.php:1478 +#: ../../include/conversation.php:1533 #: ../../extend/addon/hzaddons/hsse/hsse.php:209 #: ../../extend/addon/hzaddons/hsse/hsse.php:258 msgid "Cancel" @@ -1817,9 +1851,9 @@ msgid "Install a New Addon Repository" msgstr "Установить новый репозиторий расширений" #: ../../Zotlabs/Module/Admin/Addons.php:457 -#: ../../Zotlabs/Module/Profiles.php:801 ../../Zotlabs/Module/Cdav.php:1052 +#: ../../Zotlabs/Module/Profiles.php:841 ../../Zotlabs/Module/Cdav.php:1052 #: ../../Zotlabs/Module/Cdav.php:1388 ../../Zotlabs/Module/Oauth.php:53 -#: ../../Zotlabs/Module/Oauth.php:135 ../../Zotlabs/Module/Connedit.php:924 +#: ../../Zotlabs/Module/Oauth.php:135 ../../Zotlabs/Module/Connedit.php:748 #: ../../Zotlabs/Module/Oauth2.php:58 ../../Zotlabs/Module/Oauth2.php:142 #: ../../Zotlabs/Lib/Apps.php:542 msgid "Update" @@ -1841,7 +1875,7 @@ msgstr "Ошибки" msgid "Site settings updated." msgstr "Настройки сайта обновлены." -#: ../../Zotlabs/Module/Admin/Site.php:251 ../../include/text.php:3374 +#: ../../Zotlabs/Module/Admin/Site.php:251 ../../include/text.php:3402 #: ../../view/theme/redbasic/php/config.php:15 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:335 #: ../../extend/addon/hzaddons/cart/submodules/orderoptions.php:359 @@ -2083,7 +2117,7 @@ msgid "Advanced examples:" msgstr "Дополнительные примеры:" #: ../../Zotlabs/Module/Admin/Site.php:457 -#: ../../Zotlabs/Module/Settings/Channel.php:422 +#: ../../Zotlabs/Module/Settings/Channel.php:178 msgid "or" msgstr "или" @@ -2218,7 +2252,9 @@ msgstr "Импортировать только публичные потоки #: ../../Zotlabs/Module/Admin/Site.php:512 #: ../../Zotlabs/Module/Admin/Site.php:513 -#: ../../Zotlabs/Module/Connedit.php:877 ../../Zotlabs/Module/Connedit.php:878 +#: ../../Zotlabs/Module/Contactedit.php:423 +#: ../../Zotlabs/Module/Contactedit.php:424 +#: ../../Zotlabs/Module/Connedit.php:706 ../../Zotlabs/Module/Connedit.php:707 msgid "" "words one per line or #tags or /patterns/ or lang=xx, leave blank to import " "all posts" @@ -2480,7 +2516,7 @@ msgstr "Разрешить код" msgid "Disallow Code" msgstr "Запретить код" -#: ../../Zotlabs/Module/Admin/Channels.php:154 ../../include/nav.php:426 +#: ../../Zotlabs/Module/Admin/Channels.php:154 ../../include/nav.php:424 msgid "Channel" msgstr "Канал" @@ -2491,20 +2527,20 @@ msgstr "" #: ../../Zotlabs/Module/Admin/Channels.php:159 #: ../../Zotlabs/Module/Cdav.php:1372 ../../Zotlabs/Module/Oauth.php:111 #: ../../Zotlabs/Module/Oauth.php:137 ../../Zotlabs/Module/Chat.php:255 -#: ../../Zotlabs/Module/Group.php:153 ../../Zotlabs/Module/Connedit.php:908 +#: ../../Zotlabs/Module/Group.php:172 ../../Zotlabs/Module/Connedit.php:732 #: ../../Zotlabs/Module/Sharedwithme.php:106 #: ../../Zotlabs/Module/Oauth2.php:116 ../../Zotlabs/Module/Oauth2.php:144 #: ../../Zotlabs/Module/Wiki.php:215 ../../Zotlabs/Storage/Browser.php:377 -#: ../../Zotlabs/Lib/NativeWikiPage.php:576 +#: ../../Zotlabs/Lib/NativeWikiPage.php:582 #: ../../Zotlabs/Widget/Wiki_page_history.php:22 #: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:172 msgid "Name" msgstr "Имя" #: ../../Zotlabs/Module/Admin/Channels.php:160 -#: ../../Zotlabs/Module/Profiles.php:504 ../../Zotlabs/Module/Profiles.php:792 +#: ../../Zotlabs/Module/Profiles.php:501 ../../Zotlabs/Module/Profiles.php:832 #: ../../Zotlabs/Module/Cdav.php:1379 ../../Zotlabs/Module/Locs.php:122 -#: ../../Zotlabs/Module/Connedit.php:915 +#: ../../Zotlabs/Module/Connedit.php:739 msgid "Address" msgstr "Адрес" @@ -2687,36 +2723,36 @@ msgstr "Должен быть доступен для записи веб-сер msgid "Log level" msgstr "Уровень журнала" -#: ../../Zotlabs/Module/Item.php:472 ../../Zotlabs/Module/Pin.php:36 +#: ../../Zotlabs/Module/Item.php:466 ../../Zotlabs/Module/Pin.php:36 msgid "Unable to locate original post." msgstr "Не удалось найти оригинальную публикацию." -#: ../../Zotlabs/Module/Item.php:758 +#: ../../Zotlabs/Module/Item.php:748 msgid "Empty post discarded." msgstr "Пустая публикация отклонена." -#: ../../Zotlabs/Module/Item.php:1192 +#: ../../Zotlabs/Module/Item.php:1187 msgid "Duplicate post suppressed." msgstr "Подавлена дублирующаяся публикация." -#: ../../Zotlabs/Module/Item.php:1337 +#: ../../Zotlabs/Module/Item.php:1330 msgid "System error. Post not saved." msgstr "Системная ошибка. Публикация не сохранена." -#: ../../Zotlabs/Module/Item.php:1371 +#: ../../Zotlabs/Module/Item.php:1364 msgid "Your comment is awaiting approval." msgstr "Ваш комментарий ожидает одобрения." -#: ../../Zotlabs/Module/Item.php:1505 +#: ../../Zotlabs/Module/Item.php:1497 msgid "Unable to obtain post information from database." msgstr "Невозможно получить информацию о публикации из базы данных" -#: ../../Zotlabs/Module/Item.php:1512 +#: ../../Zotlabs/Module/Item.php:1504 #, php-format msgid "You have reached your limit of %1$.0f top level posts." msgstr "Вы достигли вашего ограничения в %1$.0f публикаций высокого уровня." -#: ../../Zotlabs/Module/Item.php:1519 +#: ../../Zotlabs/Module/Item.php:1511 #, php-format msgid "You have reached your limit of %1$.0f webpages." msgstr "Вы достигли вашего ограничения в %1$.0f страниц." @@ -2812,9 +2848,9 @@ msgid "network" msgstr "сеть" #: ../../Zotlabs/Module/Profperm.php:28 ../../Zotlabs/Module/Subthread.php:89 -#: ../../Zotlabs/Module/Import_items.php:120 ../../Zotlabs/Module/Share.php:72 +#: ../../Zotlabs/Module/Import_items.php:116 ../../Zotlabs/Module/Share.php:72 #: ../../Zotlabs/Module/Dreport.php:10 ../../Zotlabs/Module/Dreport.php:55 -#: ../../Zotlabs/Module/Like.php:342 ../../Zotlabs/Module/Group.php:95 +#: ../../Zotlabs/Module/Like.php:348 ../../Zotlabs/Module/Group.php:108 #: ../../Zotlabs/Module/Cloud.php:123 ../../Zotlabs/Web/WebServer.php:115 #: ../../include/items.php:440 #: ../../extend/addon/hzaddons/redphotos/redphotos.php:119 @@ -2832,7 +2868,7 @@ msgid "Profile Visibility Editor" msgstr "Редактор видимости профиля" #: ../../Zotlabs/Module/Profperm.php:113 ../../Zotlabs/Lib/Apps.php:368 -#: ../../include/channel.php:1844 +#: ../../include/channel.php:1879 msgid "Profile" msgstr "Профиль" @@ -2850,7 +2886,7 @@ msgid "All Connections" msgstr "Все контакты" #: ../../Zotlabs/Module/Poke.php:197 ../../Zotlabs/Lib/Apps.php:357 -#: ../../include/conversation.php:1146 +#: ../../include/conversation.php:1158 msgid "Poke" msgstr "Ткнуть" @@ -2891,7 +2927,7 @@ msgstr "Элемент не найден" #: ../../Zotlabs/Module/Editwebpage.php:143 #: ../../Zotlabs/Module/Article_edit.php:99 #: ../../Zotlabs/Module/Editblock.php:116 ../../Zotlabs/Module/Chat.php:218 -#: ../../include/conversation.php:1348 +#: ../../include/conversation.php:1362 #: ../../extend/addon/hzaddons/hsse/hsse.php:95 #: ../../extend/addon/hzaddons/mail/Mod_Mail.php:205 msgid "Insert web link" @@ -2902,7 +2938,7 @@ msgid "Edit Card" msgstr "Редактировать карточку" #: ../../Zotlabs/Module/Profiles.php:26 ../../Zotlabs/Module/Profiles.php:186 -#: ../../Zotlabs/Module/Profiles.php:243 ../../Zotlabs/Module/Profiles.php:661 +#: ../../Zotlabs/Module/Profiles.php:242 ../../Zotlabs/Module/Profiles.php:671 msgid "Profile not found." msgstr "Профиль не найден." @@ -2926,344 +2962,356 @@ msgstr "Профиль недоступен для клонирования." msgid "Profile unavailable to export." msgstr "Профиль недоступен для экспорта." -#: ../../Zotlabs/Module/Profiles.php:254 +#: ../../Zotlabs/Module/Profiles.php:253 msgid "Profile Name is required." msgstr "Требуется имя профиля." -#: ../../Zotlabs/Module/Profiles.php:461 +#: ../../Zotlabs/Module/Profiles.php:458 msgid "Marital Status" msgstr "Семейное положение" -#: ../../Zotlabs/Module/Profiles.php:465 +#: ../../Zotlabs/Module/Profiles.php:462 msgid "Romantic Partner" msgstr "Романтический партнер" -#: ../../Zotlabs/Module/Profiles.php:469 ../../Zotlabs/Module/Profiles.php:774 +#: ../../Zotlabs/Module/Profiles.php:466 ../../Zotlabs/Module/Profiles.php:814 msgid "Likes" msgstr "Нравится" -#: ../../Zotlabs/Module/Profiles.php:473 ../../Zotlabs/Module/Profiles.php:775 +#: ../../Zotlabs/Module/Profiles.php:470 ../../Zotlabs/Module/Profiles.php:815 msgid "Dislikes" msgstr "Не нравится" -#: ../../Zotlabs/Module/Profiles.php:477 ../../Zotlabs/Module/Profiles.php:782 +#: ../../Zotlabs/Module/Profiles.php:474 ../../Zotlabs/Module/Profiles.php:822 msgid "Work/Employment" msgstr "Работа / Занятость" -#: ../../Zotlabs/Module/Profiles.php:480 +#: ../../Zotlabs/Module/Profiles.php:477 msgid "Religion" msgstr "Религия" -#: ../../Zotlabs/Module/Profiles.php:484 +#: ../../Zotlabs/Module/Profiles.php:481 msgid "Political Views" msgstr "Политические взгляды" -#: ../../Zotlabs/Module/Profiles.php:488 +#: ../../Zotlabs/Module/Profiles.php:485 #: ../../extend/addon/hzaddons/openid/MysqlProvider.php:74 msgid "Gender" msgstr "Гендер" -#: ../../Zotlabs/Module/Profiles.php:492 +#: ../../Zotlabs/Module/Profiles.php:489 msgid "Sexual Preference" msgstr "Сексуальная ориентация" -#: ../../Zotlabs/Module/Profiles.php:496 +#: ../../Zotlabs/Module/Profiles.php:493 msgid "Homepage" msgstr "Домашняя страница" -#: ../../Zotlabs/Module/Profiles.php:500 +#: ../../Zotlabs/Module/Profiles.php:497 msgid "Interests" msgstr "Интересы" -#: ../../Zotlabs/Module/Profiles.php:511 ../../Zotlabs/Module/Profiles.php:736 +#: ../../Zotlabs/Module/Profiles.php:508 ../../Zotlabs/Module/Profiles.php:776 #: ../../Zotlabs/Module/Cdav.php:1014 ../../Zotlabs/Module/Locs.php:121 #: ../../Zotlabs/Module/Pubsites.php:52 ../../include/js_strings.php:25 msgid "Location" msgstr "Место" -#: ../../Zotlabs/Module/Profiles.php:596 +#: ../../Zotlabs/Module/Profiles.php:605 msgid "Profile updated." msgstr "Профиль обновлен." -#: ../../Zotlabs/Module/Profiles.php:680 -msgid "Hide your connections list from viewers of this profile" -msgstr "Скрывать от просмотра ваш список контактов в этом профиле" +#: ../../Zotlabs/Module/Profiles.php:698 +msgid "Hide my connections from viewers of this profile" +msgstr "Скрыть мои контакты от просматривающих этот профиль" + +#: ../../Zotlabs/Module/Profiles.php:711 +msgid "Publish my default profile in the network directory" +msgstr "Опубликовать мой профиль по умолчанию в каталоге сети" + +#: ../../Zotlabs/Module/Profiles.php:719 +msgid "Suggest me as a potential contact to new members" +msgstr "Предлагать меня как потенциальный новый контакт для новых участников" -#: ../../Zotlabs/Module/Profiles.php:724 +#: ../../Zotlabs/Module/Profiles.php:723 +msgid "Reveal my online status" +msgstr "Показать мой статус в сети" + +#: ../../Zotlabs/Module/Profiles.php:764 msgid "Edit Profile Details" msgstr "Редактирование профиля" -#: ../../Zotlabs/Module/Profiles.php:726 +#: ../../Zotlabs/Module/Profiles.php:766 msgid "View this profile" msgstr "Посмотреть этот профиль" -#: ../../Zotlabs/Module/Profiles.php:727 ../../Zotlabs/Module/Profiles.php:826 -#: ../../include/channel.php:1519 +#: ../../Zotlabs/Module/Profiles.php:767 ../../Zotlabs/Module/Profiles.php:871 +#: ../../include/channel.php:1553 msgid "Edit visibility" msgstr "Редактировать видимость" -#: ../../Zotlabs/Module/Profiles.php:728 +#: ../../Zotlabs/Module/Profiles.php:768 msgid "Profile Tools" msgstr "Инструменты профиля" -#: ../../Zotlabs/Module/Profiles.php:729 +#: ../../Zotlabs/Module/Profiles.php:769 msgid "Change cover photo" msgstr "Изменить фотографию обложки" -#: ../../Zotlabs/Module/Profiles.php:730 ../../include/channel.php:1489 +#: ../../Zotlabs/Module/Profiles.php:770 ../../include/channel.php:1523 msgid "Change profile photo" msgstr "Изменить фотографию профиля" -#: ../../Zotlabs/Module/Profiles.php:731 +#: ../../Zotlabs/Module/Profiles.php:771 msgid "Create a new profile using these settings" msgstr "Создать новый профиль с теми же настройками" -#: ../../Zotlabs/Module/Profiles.php:732 +#: ../../Zotlabs/Module/Profiles.php:772 msgid "Clone this profile" msgstr "Клонировать этот профиль" -#: ../../Zotlabs/Module/Profiles.php:733 +#: ../../Zotlabs/Module/Profiles.php:773 msgid "Delete this profile" msgstr "Удалить этот профиль" -#: ../../Zotlabs/Module/Profiles.php:734 +#: ../../Zotlabs/Module/Profiles.php:774 msgid "Add profile things" msgstr "Добавить в профиль" -#: ../../Zotlabs/Module/Profiles.php:735 -msgid "Personal" -msgstr "Личное" +#: ../../Zotlabs/Module/Profiles.php:775 +msgid "Basic" +msgstr "Основной" -#: ../../Zotlabs/Module/Profiles.php:737 +#: ../../Zotlabs/Module/Profiles.php:777 msgid "Relationship" msgstr "Отношения" -#: ../../Zotlabs/Module/Profiles.php:738 ../../Zotlabs/Widget/Newmember.php:51 +#: ../../Zotlabs/Module/Profiles.php:778 ../../Zotlabs/Widget/Newmember.php:51 #: ../../include/datetime.php:58 msgid "Miscellaneous" msgstr "Прочее" -#: ../../Zotlabs/Module/Profiles.php:740 +#: ../../Zotlabs/Module/Profiles.php:780 msgid "Import profile from file" msgstr "Импортировать профиль из файла" -#: ../../Zotlabs/Module/Profiles.php:741 +#: ../../Zotlabs/Module/Profiles.php:781 msgid "Export profile to file" msgstr "Экспортировать профиль в файл" -#: ../../Zotlabs/Module/Profiles.php:742 +#: ../../Zotlabs/Module/Profiles.php:782 msgid "Your gender" msgstr "Ваш пол" -#: ../../Zotlabs/Module/Profiles.php:743 +#: ../../Zotlabs/Module/Profiles.php:783 msgid "Marital status" msgstr "Семейное положение" -#: ../../Zotlabs/Module/Profiles.php:744 +#: ../../Zotlabs/Module/Profiles.php:784 msgid "Sexual preference" msgstr "Сексуальная ориентация" -#: ../../Zotlabs/Module/Profiles.php:747 +#: ../../Zotlabs/Module/Profiles.php:787 msgid "Profile name" msgstr "Имя профиля" -#: ../../Zotlabs/Module/Profiles.php:749 +#: ../../Zotlabs/Module/Profiles.php:789 msgid "This is your default profile." msgstr "Это ваш профиль по умолчанию." -#: ../../Zotlabs/Module/Profiles.php:751 +#: ../../Zotlabs/Module/Profiles.php:791 msgid "Your full name" msgstr "Ваше полное имя" -#: ../../Zotlabs/Module/Profiles.php:752 +#: ../../Zotlabs/Module/Profiles.php:792 msgid "Short title/description" msgstr "Краткий заголовок или наименование" -#: ../../Zotlabs/Module/Profiles.php:752 +#: ../../Zotlabs/Module/Profiles.php:792 msgid "Maximal 190 characters" msgstr "Не более 190 символов" -#: ../../Zotlabs/Module/Profiles.php:755 +#: ../../Zotlabs/Module/Profiles.php:795 msgid "Street address" msgstr "Улица, дом, квартира" -#: ../../Zotlabs/Module/Profiles.php:756 +#: ../../Zotlabs/Module/Profiles.php:796 msgid "Locality/City" msgstr "Населенный пункт / город" -#: ../../Zotlabs/Module/Profiles.php:757 +#: ../../Zotlabs/Module/Profiles.php:797 msgid "Region/State" msgstr "Регион / Область" -#: ../../Zotlabs/Module/Profiles.php:758 +#: ../../Zotlabs/Module/Profiles.php:798 msgid "Postal/Zip code" msgstr "Почтовый индекс" -#: ../../Zotlabs/Module/Profiles.php:759 ../../Zotlabs/Module/Cdav.php:1397 -#: ../../Zotlabs/Module/Connedit.php:933 +#: ../../Zotlabs/Module/Profiles.php:799 ../../Zotlabs/Module/Cdav.php:1397 +#: ../../Zotlabs/Module/Connedit.php:757 msgid "Country" msgstr "Страна" -#: ../../Zotlabs/Module/Profiles.php:764 +#: ../../Zotlabs/Module/Profiles.php:804 msgid "Who (if applicable)" msgstr "Кто (если применимо)" -#: ../../Zotlabs/Module/Profiles.php:764 +#: ../../Zotlabs/Module/Profiles.php:804 msgid "Examples: cathy123, Cathy Williams, cathy@example.com" msgstr "Примеры: ivan1990, Ivan Petrov, ivan@example.com" -#: ../../Zotlabs/Module/Profiles.php:765 +#: ../../Zotlabs/Module/Profiles.php:805 msgid "Since (date)" msgstr "С (дата)" -#: ../../Zotlabs/Module/Profiles.php:768 +#: ../../Zotlabs/Module/Profiles.php:808 msgid "Tell us about yourself" msgstr "Расскажите нам о себе" -#: ../../Zotlabs/Module/Profiles.php:769 +#: ../../Zotlabs/Module/Profiles.php:809 #: ../../extend/addon/hzaddons/openid/MysqlProvider.php:68 msgid "Homepage URL" msgstr "URL домашней страницы" -#: ../../Zotlabs/Module/Profiles.php:770 +#: ../../Zotlabs/Module/Profiles.php:810 msgid "Hometown" msgstr "Родной город" -#: ../../Zotlabs/Module/Profiles.php:771 +#: ../../Zotlabs/Module/Profiles.php:811 msgid "Political views" msgstr "Политические взгляды" -#: ../../Zotlabs/Module/Profiles.php:772 +#: ../../Zotlabs/Module/Profiles.php:812 msgid "Religious views" msgstr "Религиозные взгляды" -#: ../../Zotlabs/Module/Profiles.php:773 +#: ../../Zotlabs/Module/Profiles.php:813 msgid "Keywords used in directory listings" msgstr "Ключевые слова для участия в каталоге" -#: ../../Zotlabs/Module/Profiles.php:773 +#: ../../Zotlabs/Module/Profiles.php:813 msgid "Example: fishing photography software" msgstr "Например: fishing photography software" -#: ../../Zotlabs/Module/Profiles.php:776 +#: ../../Zotlabs/Module/Profiles.php:816 msgid "Musical interests" msgstr "Музыкальные интересы" -#: ../../Zotlabs/Module/Profiles.php:777 +#: ../../Zotlabs/Module/Profiles.php:817 msgid "Books, literature" msgstr "Книги, литература" -#: ../../Zotlabs/Module/Profiles.php:778 +#: ../../Zotlabs/Module/Profiles.php:818 msgid "Television" msgstr "Телевидение" -#: ../../Zotlabs/Module/Profiles.php:779 +#: ../../Zotlabs/Module/Profiles.php:819 msgid "Film/Dance/Culture/Entertainment" msgstr "Кино / танцы / культура / развлечения" -#: ../../Zotlabs/Module/Profiles.php:780 +#: ../../Zotlabs/Module/Profiles.php:820 msgid "Hobbies/Interests" msgstr "Хобби / интересы" -#: ../../Zotlabs/Module/Profiles.php:781 +#: ../../Zotlabs/Module/Profiles.php:821 msgid "Love/Romance" msgstr "Любовь / романтические отношения" -#: ../../Zotlabs/Module/Profiles.php:783 +#: ../../Zotlabs/Module/Profiles.php:823 msgid "School/Education" msgstr "Школа / образование" -#: ../../Zotlabs/Module/Profiles.php:784 +#: ../../Zotlabs/Module/Profiles.php:824 msgid "Contact information and social networks" msgstr "Информация и социальные сети для связи" -#: ../../Zotlabs/Module/Profiles.php:785 +#: ../../Zotlabs/Module/Profiles.php:825 msgid "My other channels" msgstr "Мои другие контакты" -#: ../../Zotlabs/Module/Profiles.php:787 +#: ../../Zotlabs/Module/Profiles.php:827 msgid "Communications" msgstr "Связи" -#: ../../Zotlabs/Module/Profiles.php:788 ../../Zotlabs/Module/Cdav.php:1375 -#: ../../Zotlabs/Module/Connedit.php:911 +#: ../../Zotlabs/Module/Profiles.php:828 ../../Zotlabs/Module/Cdav.php:1375 +#: ../../Zotlabs/Module/Connedit.php:735 msgid "Phone" msgstr "Телефон" -#: ../../Zotlabs/Module/Profiles.php:790 ../../Zotlabs/Module/Cdav.php:1377 -#: ../../Zotlabs/Module/Connedit.php:913 +#: ../../Zotlabs/Module/Profiles.php:830 ../../Zotlabs/Module/Cdav.php:1377 +#: ../../Zotlabs/Module/Connedit.php:737 msgid "Instant messenger" msgstr "Мессенджер" -#: ../../Zotlabs/Module/Profiles.php:791 ../../Zotlabs/Module/Cdav.php:1378 -#: ../../Zotlabs/Module/Connedit.php:914 +#: ../../Zotlabs/Module/Profiles.php:831 ../../Zotlabs/Module/Cdav.php:1378 +#: ../../Zotlabs/Module/Connedit.php:738 msgid "Website" msgstr "Веб-сайт" -#: ../../Zotlabs/Module/Profiles.php:793 ../../Zotlabs/Module/Cdav.php:1380 -#: ../../Zotlabs/Module/Connedit.php:916 +#: ../../Zotlabs/Module/Profiles.php:833 ../../Zotlabs/Module/Cdav.php:1380 +#: ../../Zotlabs/Module/Connedit.php:740 msgid "Note" msgstr "Заметка" -#: ../../Zotlabs/Module/Profiles.php:794 ../../Zotlabs/Module/Cdav.php:1381 -#: ../../Zotlabs/Module/Connedit.php:917 ../../include/event.php:1422 -#: ../../include/connections.php:724 +#: ../../Zotlabs/Module/Profiles.php:834 ../../Zotlabs/Module/Cdav.php:1381 +#: ../../Zotlabs/Module/Connedit.php:741 ../../include/event.php:1422 +#: ../../include/connections.php:751 msgid "Mobile" msgstr "Мобильный" -#: ../../Zotlabs/Module/Profiles.php:795 ../../Zotlabs/Module/Cdav.php:1382 -#: ../../Zotlabs/Module/Connedit.php:918 +#: ../../Zotlabs/Module/Profiles.php:835 ../../Zotlabs/Module/Cdav.php:1382 +#: ../../Zotlabs/Module/Connedit.php:742 #: ../../Zotlabs/Widget/Notifications.php:36 ../../include/event.php:1423 -#: ../../include/connections.php:725 +#: ../../include/connections.php:752 msgid "Home" msgstr "Домашний" -#: ../../Zotlabs/Module/Profiles.php:796 ../../Zotlabs/Module/Cdav.php:1383 -#: ../../Zotlabs/Module/Connedit.php:919 ../../include/event.php:1426 -#: ../../include/connections.php:728 +#: ../../Zotlabs/Module/Profiles.php:836 ../../Zotlabs/Module/Cdav.php:1383 +#: ../../Zotlabs/Module/Connedit.php:743 ../../include/event.php:1426 +#: ../../include/connections.php:755 msgid "Work" msgstr "Рабочий" -#: ../../Zotlabs/Module/Profiles.php:797 ../../Zotlabs/Module/Cdav.php:1384 -#: ../../Zotlabs/Module/Connedit.php:920 -#: ../../Zotlabs/Access/PermissionRoles.php:310 ../../include/event.php:1429 -#: ../../include/event.php:1436 ../../include/connections.php:731 -#: ../../include/connections.php:738 ../../include/selectors.php:60 +#: ../../Zotlabs/Module/Profiles.php:837 ../../Zotlabs/Module/Cdav.php:1384 +#: ../../Zotlabs/Module/Connedit.php:744 +#: ../../Zotlabs/Access/PermissionRoles.php:360 ../../include/event.php:1429 +#: ../../include/event.php:1436 ../../include/connections.php:758 +#: ../../include/connections.php:765 ../../include/selectors.php:60 #: ../../include/selectors.php:77 ../../include/selectors.php:115 #: ../../include/selectors.php:151 msgid "Other" msgstr "Другой" -#: ../../Zotlabs/Module/Profiles.php:798 ../../Zotlabs/Module/Cdav.php:1385 -#: ../../Zotlabs/Module/Connedit.php:921 +#: ../../Zotlabs/Module/Profiles.php:838 ../../Zotlabs/Module/Cdav.php:1385 +#: ../../Zotlabs/Module/Connedit.php:745 msgid "Add Contact" msgstr "Добавить контакт" -#: ../../Zotlabs/Module/Profiles.php:799 ../../Zotlabs/Module/Cdav.php:1386 -#: ../../Zotlabs/Module/Connedit.php:922 +#: ../../Zotlabs/Module/Profiles.php:839 ../../Zotlabs/Module/Cdav.php:1386 +#: ../../Zotlabs/Module/Connedit.php:746 msgid "Add Field" msgstr "Добавить поле" -#: ../../Zotlabs/Module/Profiles.php:800 ../../Zotlabs/Module/Cdav.php:1058 +#: ../../Zotlabs/Module/Profiles.php:840 ../../Zotlabs/Module/Cdav.php:1058 #: ../../Zotlabs/Module/Cdav.php:1387 ../../Zotlabs/Module/Layouts.php:185 #: ../../Zotlabs/Module/Blocks.php:159 ../../Zotlabs/Module/New_channel.php:189 #: ../../Zotlabs/Module/Menu.php:182 ../../Zotlabs/Module/Webpages.php:251 -#: ../../Zotlabs/Module/Connedit.php:923 ../../Zotlabs/Storage/Browser.php:365 +#: ../../Zotlabs/Module/Connedit.php:747 ../../Zotlabs/Storage/Browser.php:365 #: ../../Zotlabs/Storage/Browser.php:538 ../../Zotlabs/Widget/Cdav.php:140 #: ../../Zotlabs/Widget/Cdav.php:178 msgid "Create" msgstr "Создать" -#: ../../Zotlabs/Module/Profiles.php:822 ../../include/channel.php:1515 +#: ../../Zotlabs/Module/Profiles.php:867 ../../include/channel.php:1549 msgid "Profile Image" msgstr "Изображение профиля" -#: ../../Zotlabs/Module/Profiles.php:832 ../../include/channel.php:1496 -#: ../../include/nav.php:115 +#: ../../Zotlabs/Module/Profiles.php:877 ../../include/channel.php:1530 +#: ../../include/nav.php:113 msgid "Edit Profiles" msgstr "Редактирование профилей" -#: ../../Zotlabs/Module/Profiles.php:833 ../../Zotlabs/Module/Manage.php:137 +#: ../../Zotlabs/Module/Profiles.php:878 ../../Zotlabs/Module/Manage.php:137 #: ../../Zotlabs/Module/Wiki.php:211 msgid "Create New" msgstr "Создать новый" @@ -3334,25 +3382,25 @@ msgstr "Выбрать тег для удаления:" #: ../../Zotlabs/Module/Connections.php:58 #: ../../Zotlabs/Module/Connections.php:116 -#: ../../Zotlabs/Module/Connections.php:274 +#: ../../Zotlabs/Module/Connections.php:282 msgid "Active" msgstr "Активен" #: ../../Zotlabs/Module/Connections.php:63 #: ../../Zotlabs/Module/Connections.php:182 -#: ../../Zotlabs/Module/Connections.php:279 +#: ../../Zotlabs/Module/Connections.php:287 msgid "Blocked" msgstr "Заблокирован" #: ../../Zotlabs/Module/Connections.php:68 #: ../../Zotlabs/Module/Connections.php:189 -#: ../../Zotlabs/Module/Connections.php:278 +#: ../../Zotlabs/Module/Connections.php:286 msgid "Ignored" msgstr "Игнорируется" #: ../../Zotlabs/Module/Connections.php:73 #: ../../Zotlabs/Module/Connections.php:203 -#: ../../Zotlabs/Module/Connections.php:277 +#: ../../Zotlabs/Module/Connections.php:285 msgid "Hidden" msgstr "Скрыт" @@ -3369,7 +3417,8 @@ msgstr "Новые" #: ../../Zotlabs/Module/Connections.php:97 #: ../../Zotlabs/Module/Connections.php:111 -#: ../../Zotlabs/Module/Connedit.php:712 ../../Zotlabs/Widget/Affinity.php:34 +#: ../../Zotlabs/Module/Contactedit.php:299 +#: ../../Zotlabs/Module/Connedit.php:583 ../../Zotlabs/Widget/Affinity.php:34 msgid "All" msgstr "Все" @@ -3410,140 +3459,157 @@ msgstr "Показать только скрытые контакты" msgid "Show all connections" msgstr "Просмотр всех контактов" -#: ../../Zotlabs/Module/Connections.php:275 +#: ../../Zotlabs/Module/Connections.php:283 msgid "Pending approval" msgstr "Ожидающие подтверждения" -#: ../../Zotlabs/Module/Connections.php:276 +#: ../../Zotlabs/Module/Connections.php:284 msgid "Archived" msgstr "Зархивирован" -#: ../../Zotlabs/Module/Connections.php:280 +#: ../../Zotlabs/Module/Connections.php:288 msgid "Not connected at this location" msgstr "Не подключено в этом месте" -#: ../../Zotlabs/Module/Connections.php:289 -#: ../../Zotlabs/Module/Viewconnections.php:80 ../../include/text.php:1039 +#: ../../Zotlabs/Module/Connections.php:297 +#: ../../Zotlabs/Module/Viewconnections.php:80 ../../include/text.php:1036 msgid "Accepts" msgstr "Принимает" -#: ../../Zotlabs/Module/Connections.php:292 -#: ../../Zotlabs/Module/Viewconnections.php:83 ../../include/text.php:1042 +#: ../../Zotlabs/Module/Connections.php:300 +#: ../../Zotlabs/Module/Viewconnections.php:83 ../../include/text.php:1039 msgid "Comments" msgstr "комментарии" -#: ../../Zotlabs/Module/Connections.php:297 -#: ../../Zotlabs/Module/Viewconnections.php:88 ../../include/text.php:1047 +#: ../../Zotlabs/Module/Connections.php:305 +#: ../../Zotlabs/Module/Viewconnections.php:88 ../../include/text.php:1044 msgid "Stream items" msgstr "публикации в потоке" -#: ../../Zotlabs/Module/Connections.php:302 -#: ../../Zotlabs/Module/Viewconnections.php:93 ../../include/text.php:1052 +#: ../../Zotlabs/Module/Connections.php:310 +#: ../../Zotlabs/Module/Viewconnections.php:93 ../../include/text.php:1049 msgid "Wall posts" msgstr "публикации на стене" -#: ../../Zotlabs/Module/Connections.php:306 -#: ../../Zotlabs/Module/Viewconnections.php:97 ../../include/text.php:1056 +#: ../../Zotlabs/Module/Connections.php:314 +#: ../../Zotlabs/Module/Viewconnections.php:97 ../../include/text.php:1053 msgid "Nothing" msgstr "ничего" -#: ../../Zotlabs/Module/Connections.php:319 +#: ../../Zotlabs/Module/Connections.php:327 #, php-format msgid "%1$s [%2$s]" msgstr "" -#: ../../Zotlabs/Module/Connections.php:320 +#: ../../Zotlabs/Module/Connections.php:328 msgid "Edit connection" msgstr "Редактировать контакт" -#: ../../Zotlabs/Module/Connections.php:322 +#: ../../Zotlabs/Module/Connections.php:330 msgid "Delete connection" msgstr "Удалить контакт" -#: ../../Zotlabs/Module/Connections.php:331 +#: ../../Zotlabs/Module/Connections.php:339 msgid "Channel address" msgstr "Адрес канала" -#: ../../Zotlabs/Module/Connections.php:333 +#: ../../Zotlabs/Module/Connections.php:341 #: ../../Zotlabs/Widget/Notifications.php:16 ../../include/features.php:290 msgid "Network" msgstr "Сеть" -#: ../../Zotlabs/Module/Connections.php:336 +#: ../../Zotlabs/Module/Connections.php:344 msgid "Call" msgstr "Вызов" -#: ../../Zotlabs/Module/Connections.php:338 +#: ../../Zotlabs/Module/Connections.php:346 msgid "Status" msgstr "Статус" -#: ../../Zotlabs/Module/Connections.php:340 +#: ../../Zotlabs/Module/Connections.php:348 msgid "Connected" msgstr "Подключено" -#: ../../Zotlabs/Module/Connections.php:342 +#: ../../Zotlabs/Module/Connections.php:350 +#: ../../Zotlabs/Module/Contactedit.php:455 msgid "Approve connection" msgstr "Утвердить контакт" -#: ../../Zotlabs/Module/Connections.php:344 +#: ../../Zotlabs/Module/Connections.php:352 msgid "Ignore connection" msgstr "Игнорировать контакт" -#: ../../Zotlabs/Module/Connections.php:345 -#: ../../Zotlabs/Module/Connedit.php:629 +#: ../../Zotlabs/Module/Connections.php:353 +#: ../../Zotlabs/Module/Contactedit.php:639 +#: ../../Zotlabs/Module/Connedit.php:516 msgid "Ignore" msgstr "Игнорировать" -#: ../../Zotlabs/Module/Connections.php:346 +#: ../../Zotlabs/Module/Connections.php:354 msgid "Recent activity" msgstr "Последние действия" -#: ../../Zotlabs/Module/Connections.php:350 ../../Zotlabs/Module/Suggest.php:69 +#: ../../Zotlabs/Module/Connections.php:358 ../../Zotlabs/Module/Suggest.php:69 #: ../../Zotlabs/Module/Directory.php:369 #: ../../Zotlabs/Widget/Suggestions.php:46 ../../Zotlabs/Widget/Follow.php:32 -#: ../../include/channel.php:1576 ../../include/connections.php:110 -#: ../../include/conversation.php:1106 +#: ../../include/channel.php:1610 ../../include/connections.php:112 +#: ../../include/conversation.php:1110 msgid "Connect" msgstr "Подключить" -#: ../../Zotlabs/Module/Connections.php:352 +#: ../../Zotlabs/Module/Connections.php:360 msgid "Connect at this location" msgstr "Подключить в этом месте" -#: ../../Zotlabs/Module/Connections.php:375 ../../Zotlabs/Lib/Apps.php:339 -#: ../../include/features.php:133 ../../include/text.php:1031 +#: ../../Zotlabs/Module/Connections.php:369 ../../Zotlabs/Widget/Follow.php:22 +#, php-format +msgid "You have %1$.0f of %2$.0f allowed connections." +msgstr "У вас есть %1$.0f из %2$.0f разрешенных контактов." + +#: ../../Zotlabs/Module/Connections.php:391 ../../Zotlabs/Lib/Apps.php:339 +#: ../../include/features.php:133 ../../include/text.php:1028 msgid "Connections" msgstr "Контакты" -#: ../../Zotlabs/Module/Connections.php:379 ../../Zotlabs/Module/Search.php:44 +#: ../../Zotlabs/Module/Connections.php:395 ../../Zotlabs/Module/Search.php:45 #: ../../Zotlabs/Lib/Apps.php:359 ../../Zotlabs/Widget/Sitesearch.php:31 -#: ../../Zotlabs/Widget/Activity_filter.php:203 ../../include/nav.php:192 -#: ../../include/acl_selectors.php:149 ../../include/text.php:1145 -#: ../../include/text.php:1157 +#: ../../Zotlabs/Widget/Activity_filter.php:203 ../../include/nav.php:190 +#: ../../include/acl_selectors.php:149 ../../include/text.php:1142 +#: ../../include/text.php:1154 msgid "Search" msgstr "Поиск" -#: ../../Zotlabs/Module/Connections.php:380 +#: ../../Zotlabs/Module/Connections.php:396 +#: ../../Zotlabs/Module/Connedit.php:686 +msgid "Contact role" +msgstr "Роль контакта" + +#: ../../Zotlabs/Module/Connections.php:397 msgid "Search your connections" msgstr "Поиск ваших контактов" -#: ../../Zotlabs/Module/Connections.php:381 -msgid "Connections search" -msgstr "Поиск контаков" +#: ../../Zotlabs/Module/Connections.php:398 +msgid "Contact search" +msgstr "Поиск контакта" -#: ../../Zotlabs/Module/Connections.php:382 +#: ../../Zotlabs/Module/Connections.php:399 #: ../../Zotlabs/Module/Directory.php:432 #: ../../Zotlabs/Module/Directory.php:437 ../../include/contact_widgets.php:23 msgid "Find" msgstr "Поиск" +#: ../../Zotlabs/Module/Connections.php:405 +#: ../../Zotlabs/Module/Contactedit.php:397 +msgid "This is a group/forum channel" +msgstr "Это канал группы или форума" + #: ../../Zotlabs/Module/Profile_photo.php:93 #: ../../Zotlabs/Module/Cover_photo.php:85 msgid "Image uploaded but image cropping failed." msgstr "Изображение загружено но обрезка не удалась." #: ../../Zotlabs/Module/Profile_photo.php:147 -#: ../../Zotlabs/Module/Profile_photo.php:284 +#: ../../Zotlabs/Module/Profile_photo.php:283 #: ../../include/photo/photo_driver.php:434 msgid "Profile Photos" msgstr "Фотографии профиля" @@ -3561,132 +3627,132 @@ msgid "" msgstr "Если новая фотография не отображается немедленно то нажмите Shift + \"Обновить\" для очистки кэша браузера" #: ../../Zotlabs/Module/Profile_photo.php:261 -#: ../../Zotlabs/Module/Cover_photo.php:241 ../../include/photos.php:199 +#: ../../Zotlabs/Module/Cover_photo.php:241 ../../include/photos.php:198 msgid "Unable to process image" msgstr "Не удается обработать изображение" -#: ../../Zotlabs/Module/Profile_photo.php:296 +#: ../../Zotlabs/Module/Profile_photo.php:293 #: ../../Zotlabs/Module/Cover_photo.php:265 msgid "Image upload failed." msgstr "Загрузка изображения не удалась." -#: ../../Zotlabs/Module/Profile_photo.php:315 +#: ../../Zotlabs/Module/Profile_photo.php:312 #: ../../Zotlabs/Module/Cover_photo.php:282 msgid "Unable to process image." msgstr "Невозможно обработать изображение." -#: ../../Zotlabs/Module/Profile_photo.php:379 -#: ../../Zotlabs/Module/Profile_photo.php:431 +#: ../../Zotlabs/Module/Profile_photo.php:376 +#: ../../Zotlabs/Module/Profile_photo.php:428 #: ../../Zotlabs/Module/Cover_photo.php:367 #: ../../Zotlabs/Module/Cover_photo.php:382 msgid "Photo not available." msgstr "Фотография недоступна." -#: ../../Zotlabs/Module/Profile_photo.php:495 +#: ../../Zotlabs/Module/Profile_photo.php:492 msgid "" "Your default profile photo is visible to anybody on the internet. Profile " "photos for alternate profiles will inherit the permissions of the profile" msgstr "Фотография вашего профиля по умолчанию видна всем в Интернете. Фотографияпрофиля для альтернативных профилей наследуют разрешения текущего профиля" -#: ../../Zotlabs/Module/Profile_photo.php:495 +#: ../../Zotlabs/Module/Profile_photo.php:492 msgid "" "Your profile photo is visible to anybody on the internet and may be " "distributed to other websites." msgstr "Фотография вашего профиля видна всем в Интернете и может быть отправлена на другие сайты." -#: ../../Zotlabs/Module/Profile_photo.php:497 +#: ../../Zotlabs/Module/Profile_photo.php:494 #: ../../Zotlabs/Module/Cover_photo.php:420 msgid "Upload File:" msgstr "Загрузить файл:" -#: ../../Zotlabs/Module/Profile_photo.php:498 +#: ../../Zotlabs/Module/Profile_photo.php:495 #: ../../Zotlabs/Module/Cover_photo.php:421 msgid "Select a profile:" msgstr "Выбрать профиль:" -#: ../../Zotlabs/Module/Profile_photo.php:499 +#: ../../Zotlabs/Module/Profile_photo.php:496 msgid "Use Photo for Profile" msgstr "Использовать фотографию для профиля" -#: ../../Zotlabs/Module/Profile_photo.php:499 +#: ../../Zotlabs/Module/Profile_photo.php:496 msgid "Change Profile Photo" msgstr "Изменить фотографию профиля" -#: ../../Zotlabs/Module/Profile_photo.php:500 +#: ../../Zotlabs/Module/Profile_photo.php:497 msgid "Use" msgstr "Использовать" -#: ../../Zotlabs/Module/Profile_photo.php:505 -#: ../../Zotlabs/Module/Profile_photo.php:506 +#: ../../Zotlabs/Module/Profile_photo.php:502 +#: ../../Zotlabs/Module/Profile_photo.php:503 #: ../../Zotlabs/Module/Cover_photo.php:426 #: ../../Zotlabs/Module/Cover_photo.php:427 msgid "Use a photo from your albums" msgstr "Использовать фотографию из ваших альбомов" -#: ../../Zotlabs/Module/Profile_photo.php:508 +#: ../../Zotlabs/Module/Profile_photo.php:505 #: ../../Zotlabs/Module/Cover_photo.php:429 ../../Zotlabs/Module/Wiki.php:399 -#: ../../include/conversation.php:1465 ../../include/conversation.php:1518 +#: ../../include/conversation.php:1479 ../../include/conversation.php:1532 #: ../../extend/addon/hzaddons/hsse/hsse.php:210 #: ../../extend/addon/hzaddons/hsse/hsse.php:257 msgid "OK" msgstr "" -#: ../../Zotlabs/Module/Profile_photo.php:509 +#: ../../Zotlabs/Module/Profile_photo.php:506 #: ../../Zotlabs/Module/Cover_photo.php:430 ../../Zotlabs/Module/Wiki.php:400 -#: ../../include/conversation.php:1390 +#: ../../include/conversation.php:1404 #: ../../extend/addon/hzaddons/hsse/hsse.php:139 msgid "Choose images to embed" msgstr "Выбрать изображения для встраивания" -#: ../../Zotlabs/Module/Profile_photo.php:510 +#: ../../Zotlabs/Module/Profile_photo.php:507 #: ../../Zotlabs/Module/Cover_photo.php:431 ../../Zotlabs/Module/Wiki.php:401 -#: ../../include/conversation.php:1391 +#: ../../include/conversation.php:1405 #: ../../extend/addon/hzaddons/hsse/hsse.php:140 msgid "Choose an album" msgstr "Выбрать альбом" -#: ../../Zotlabs/Module/Profile_photo.php:511 +#: ../../Zotlabs/Module/Profile_photo.php:508 #: ../../Zotlabs/Module/Cover_photo.php:432 ../../Zotlabs/Module/Wiki.php:402 msgid "Choose a different album" msgstr "Выбрать другой альбом" -#: ../../Zotlabs/Module/Profile_photo.php:512 +#: ../../Zotlabs/Module/Profile_photo.php:509 #: ../../Zotlabs/Module/Cover_photo.php:433 ../../Zotlabs/Module/Wiki.php:403 -#: ../../include/conversation.php:1393 +#: ../../include/conversation.php:1407 #: ../../extend/addon/hzaddons/hsse/hsse.php:142 msgid "Error getting album list" msgstr "Ошибка получения списка альбомов" -#: ../../Zotlabs/Module/Profile_photo.php:513 +#: ../../Zotlabs/Module/Profile_photo.php:510 #: ../../Zotlabs/Module/Cover_photo.php:434 ../../Zotlabs/Module/Wiki.php:404 -#: ../../include/conversation.php:1394 +#: ../../include/conversation.php:1408 #: ../../extend/addon/hzaddons/hsse/hsse.php:143 msgid "Error getting photo link" msgstr "Ошибка получения ссылки на фотографию" -#: ../../Zotlabs/Module/Profile_photo.php:514 +#: ../../Zotlabs/Module/Profile_photo.php:511 #: ../../Zotlabs/Module/Cover_photo.php:435 ../../Zotlabs/Module/Wiki.php:405 -#: ../../include/conversation.php:1395 +#: ../../include/conversation.php:1409 #: ../../extend/addon/hzaddons/hsse/hsse.php:144 msgid "Error getting album" msgstr "Ошибка получения альбома" -#: ../../Zotlabs/Module/Profile_photo.php:516 +#: ../../Zotlabs/Module/Profile_photo.php:513 #: ../../Zotlabs/Module/Cover_photo.php:438 msgid "Select existing photo" msgstr "Выбрать существующую фотографию" -#: ../../Zotlabs/Module/Profile_photo.php:535 +#: ../../Zotlabs/Module/Profile_photo.php:532 #: ../../Zotlabs/Module/Cover_photo.php:455 msgid "Crop Image" msgstr "Обрезать изображение" -#: ../../Zotlabs/Module/Profile_photo.php:536 +#: ../../Zotlabs/Module/Profile_photo.php:533 #: ../../Zotlabs/Module/Cover_photo.php:456 msgid "Please adjust the image cropping for optimum viewing." msgstr "Пожалуйста настройте обрезку изображения для оптимального просмотра." -#: ../../Zotlabs/Module/Profile_photo.php:538 +#: ../../Zotlabs/Module/Profile_photo.php:535 #: ../../Zotlabs/Module/Cover_photo.php:458 msgid "Done Editing" msgstr "Закончить редактирование" @@ -3791,37 +3857,37 @@ msgstr "Не удалось получить содержимое календа msgid "Categories" msgstr "Категории" -#: ../../Zotlabs/Module/Cdav.php:1373 ../../Zotlabs/Module/Connedit.php:909 +#: ../../Zotlabs/Module/Cdav.php:1373 ../../Zotlabs/Module/Connedit.php:733 msgid "Organisation" msgstr "Организация" -#: ../../Zotlabs/Module/Cdav.php:1374 ../../Zotlabs/Module/Connedit.php:910 +#: ../../Zotlabs/Module/Cdav.php:1374 ../../Zotlabs/Module/Connedit.php:734 #: ../../extend/addon/hzaddons/workflow/workflow.php:2617 #: ../../extend/addon/hzaddons/workflow/workflow.php:2678 msgid "Title" msgstr "Наименование" -#: ../../Zotlabs/Module/Cdav.php:1391 ../../Zotlabs/Module/Connedit.php:927 +#: ../../Zotlabs/Module/Cdav.php:1391 ../../Zotlabs/Module/Connedit.php:751 msgid "P.O. Box" msgstr "абонентский ящик" -#: ../../Zotlabs/Module/Cdav.php:1392 ../../Zotlabs/Module/Connedit.php:928 +#: ../../Zotlabs/Module/Cdav.php:1392 ../../Zotlabs/Module/Connedit.php:752 msgid "Additional" msgstr "Дополнительно" -#: ../../Zotlabs/Module/Cdav.php:1393 ../../Zotlabs/Module/Connedit.php:929 +#: ../../Zotlabs/Module/Cdav.php:1393 ../../Zotlabs/Module/Connedit.php:753 msgid "Street" msgstr "Улица" -#: ../../Zotlabs/Module/Cdav.php:1394 ../../Zotlabs/Module/Connedit.php:930 +#: ../../Zotlabs/Module/Cdav.php:1394 ../../Zotlabs/Module/Connedit.php:754 msgid "Locality" msgstr "Населённый пункт" -#: ../../Zotlabs/Module/Cdav.php:1395 ../../Zotlabs/Module/Connedit.php:931 +#: ../../Zotlabs/Module/Cdav.php:1395 ../../Zotlabs/Module/Connedit.php:755 msgid "Region" msgstr "Регион" -#: ../../Zotlabs/Module/Cdav.php:1396 ../../Zotlabs/Module/Connedit.php:932 +#: ../../Zotlabs/Module/Cdav.php:1396 ../../Zotlabs/Module/Connedit.php:756 msgid "ZIP Code" msgstr "Индекс" @@ -3989,7 +4055,7 @@ msgid "System Notifications" msgstr "Системные оповещения " #: ../../Zotlabs/Module/Notifications.php:111 -#: ../../Zotlabs/Lib/ThreadItem.php:484 +#: ../../Zotlabs/Lib/ThreadItem.php:507 msgid "Mark all seen" msgstr "Отметить как просмотренное" @@ -4008,7 +4074,7 @@ msgstr "Видимо для:" #: ../../Zotlabs/Module/Editlayout.php:31 ../../Zotlabs/Module/Webpages.php:39 #: ../../Zotlabs/Module/Profile.php:27 ../../Zotlabs/Module/Articles.php:43 #: ../../Zotlabs/Module/Achievements.php:15 ../../Zotlabs/Module/Hcard.php:12 -#: ../../include/channel.php:1394 +#: ../../include/channel.php:1427 #: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:49 msgid "Requested profile is not available." msgstr "Запрашиваемый профиль не доступен." @@ -4069,16 +4135,16 @@ msgid "View Common Connections" msgstr "Просмотр общий контактов" #: ../../Zotlabs/Module/Subthread.php:115 ../../Zotlabs/Module/Tagger.php:71 -#: ../../Zotlabs/Module/Like.php:439 ../../Zotlabs/Lib/Activity.php:3306 -#: ../../include/conversation.php:128 ../../include/text.php:2251 +#: ../../Zotlabs/Module/Like.php:445 ../../Zotlabs/Lib/Activity.php:3389 +#: ../../include/conversation.php:128 ../../include/text.php:2279 #: ../../extend/addon/hzaddons/redphotos/redphotohelper.php:71 -#: ../../extend/addon/hzaddons/pubcrawl/as.php:1940 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1943 #: ../../extend/addon/hzaddons/diaspora/Receiver.php:1626 msgid "photo" msgstr "фото" -#: ../../Zotlabs/Module/Subthread.php:115 ../../Zotlabs/Module/Like.php:439 -#: ../../extend/addon/hzaddons/pubcrawl/as.php:1940 +#: ../../Zotlabs/Module/Subthread.php:115 ../../Zotlabs/Module/Like.php:445 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1943 #: ../../extend/addon/hzaddons/diaspora/Receiver.php:1626 msgid "status" msgstr "статус" @@ -4122,41 +4188,56 @@ msgstr "Запись цензурирована" msgid "Entry uncensored" msgstr "Запись нецензурирована" -#: ../../Zotlabs/Module/Import_items.php:48 ../../Zotlabs/Module/Import.php:72 -msgid "Nothing to import." -msgstr "Ничего импортировать." - -#: ../../Zotlabs/Module/Import_items.php:72 ../../Zotlabs/Module/Import.php:87 -#: ../../Zotlabs/Module/Import.php:102 -msgid "Unable to download data from old server" -msgstr "Невозможно загрузить данные со старого сервера" - -#: ../../Zotlabs/Module/Import_items.php:77 ../../Zotlabs/Module/Import.php:109 -msgid "Imported file is empty." -msgstr "Импортированный файл пуст." - -#: ../../Zotlabs/Module/Import_items.php:93 -#, php-format -msgid "Warning: Database versions differ by %1$d updates." -msgstr "Предупреждение: Версия базы данных отличается от %1$d обновления." - -#: ../../Zotlabs/Module/Import_items.php:108 -msgid "Import completed" -msgstr "Импорт завершён." +#: ../../Zotlabs/Module/Import_items.php:50 +msgid "Not a zip file or zip file corrupted." +msgstr "Не zip файл или повреждённый zip файл." -#: ../../Zotlabs/Module/Import_items.php:125 +#: ../../Zotlabs/Module/Import_items.php:121 msgid "Import Items" msgstr "Импортировать объекты" -#: ../../Zotlabs/Module/Import_items.php:126 +#: ../../Zotlabs/Module/Import_items.php:122 msgid "Use this form to import existing posts and content from an export file." msgstr "Используйте эту форму для импорта существующих публикаций и содержимого из файла." -#: ../../Zotlabs/Module/Import_items.php:127 -#: ../../Zotlabs/Module/Import.php:585 +#: ../../Zotlabs/Module/Import_items.php:123 +#: ../../Zotlabs/Module/Import.php:594 msgid "File to Upload" msgstr "Файл для загрузки" +#: ../../Zotlabs/Module/Import_items.php:136 +#: ../../Zotlabs/Module/Import.php:107 +msgid "Imported file is empty." +msgstr "Импортированный файл пуст." + +#: ../../Zotlabs/Module/Import_items.php:159 +msgid "Content import completed" +msgstr "Импорт содержимого завершён" + +#: ../../Zotlabs/Module/Import_items.php:164 +msgid "Chatroom import completed" +msgstr "Импорт комнат чатов завершён" + +#: ../../Zotlabs/Module/Import_items.php:170 +msgid "Channel calendar import 1/2 completed" +msgstr "Импорт календаря канала завершён на 1/2" + +#: ../../Zotlabs/Module/Import_items.php:176 +msgid "Channel calendar import 2/2 completed" +msgstr "Импорт календаря канала завершён на 2/2" + +#: ../../Zotlabs/Module/Import_items.php:181 +msgid "Menu import completed" +msgstr "Импорт меню завершён" + +#: ../../Zotlabs/Module/Import_items.php:186 +msgid "Wiki import completed" +msgstr "Импорт wiki завершён" + +#: ../../Zotlabs/Module/Import_items.php:191 +msgid "Webpages import completed" +msgstr "Импорт веб-страниц завершён" + #: ../../Zotlabs/Module/Page.php:173 msgid "" "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " @@ -4167,134 +4248,135 @@ msgid "" "non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." msgstr "" -#: ../../Zotlabs/Module/Regate.php:81 +#: ../../Zotlabs/Module/Regate.php:84 msgid "Email resent" msgstr "Электронная почта повторно отправлена" -#: ../../Zotlabs/Module/Regate.php:81 +#: ../../Zotlabs/Module/Regate.php:84 msgid "Email resend failed" msgstr "Ошибка повторной отправки электронной почты" -#: ../../Zotlabs/Module/Regate.php:106 +#: ../../Zotlabs/Module/Regate.php:109 msgid "Verification successful" msgstr "Проверка прошла успешно" -#: ../../Zotlabs/Module/Regate.php:150 +#: ../../Zotlabs/Module/Regate.php:153 msgid "Account successfull created" msgstr "Учётная запись успешно создана" -#: ../../Zotlabs/Module/Regate.php:191 +#: ../../Zotlabs/Module/Regate.php:211 msgid "Channel successfull created" msgstr "Канал успешно создан" -#: ../../Zotlabs/Module/Regate.php:197 +#: ../../Zotlabs/Module/Regate.php:217 msgid "Automatic channel creation failed. Please create a channel." msgstr "Автоматической создание канала не удалось. Пожалуйста создайте канал." -#: ../../Zotlabs/Module/Regate.php:209 +#: ../../Zotlabs/Module/Regate.php:229 msgid "Account creation error" msgstr "Ошибка создания учётной записи" -#: ../../Zotlabs/Module/Regate.php:221 +#: ../../Zotlabs/Module/Regate.php:241 msgid "Verify failed" msgstr "Проверка не удалась" -#: ../../Zotlabs/Module/Regate.php:226 +#: ../../Zotlabs/Module/Regate.php:246 msgid "Token verification failed" msgstr "Неверный проверочный код" -#: ../../Zotlabs/Module/Regate.php:231 +#: ../../Zotlabs/Module/Regate.php:251 msgid "Request not inside time frame" msgstr "Запрос в не установленные сроки " -#: ../../Zotlabs/Module/Regate.php:237 ../../Zotlabs/Module/Regate.php:267 +#: ../../Zotlabs/Module/Regate.php:257 ../../Zotlabs/Module/Regate.php:287 msgid "Identity unknown" msgstr "Личность не установлена" -#: ../../Zotlabs/Module/Regate.php:243 +#: ../../Zotlabs/Module/Regate.php:263 msgid "dId2 mistaken" msgstr "ошибочный dId2" -#: ../../Zotlabs/Module/Regate.php:271 +#: ../../Zotlabs/Module/Regate.php:291 msgid "Your Registration ID" msgstr "Идентификатор вашей регистрации" -#: ../../Zotlabs/Module/Regate.php:284 ../../Zotlabs/Module/Regate.php:376 -#: ../../Zotlabs/Module/Regate.php:408 +#: ../../Zotlabs/Module/Regate.php:304 ../../Zotlabs/Module/Regate.php:396 +#: ../../Zotlabs/Module/Regate.php:428 msgid "Registration verification" msgstr "Проверка регистрации" -#: ../../Zotlabs/Module/Regate.php:291 ../../Zotlabs/Module/Regate.php:413 +#: ../../Zotlabs/Module/Regate.php:311 ../../Zotlabs/Module/Regate.php:433 msgid "Hold on, you can start verification in" msgstr "Подождите, вы можете начать проверку через " -#: ../../Zotlabs/Module/Regate.php:292 +#: ../../Zotlabs/Module/Regate.php:312 msgid "Please remember your verification token for ID" msgstr "Пожалуйста, запомните свой код подтверждения для идентификации" -#: ../../Zotlabs/Module/Regate.php:294 +#: ../../Zotlabs/Module/Regate.php:314 msgid "Token validity" msgstr "Срок действия кода" -#: ../../Zotlabs/Module/Regate.php:330 +#: ../../Zotlabs/Module/Regate.php:350 msgid "Resend email" msgstr "Отправить электронное письмо повторно" -#: ../../Zotlabs/Module/Regate.php:335 +#: ../../Zotlabs/Module/Regate.php:355 msgid "Registration status" msgstr "Статус регистрации" -#: ../../Zotlabs/Module/Regate.php:338 +#: ../../Zotlabs/Module/Regate.php:358 msgid "Verification successful!" msgstr "Проверка прошла успешно! " -#: ../../Zotlabs/Module/Regate.php:339 +#: ../../Zotlabs/Module/Regate.php:359 msgid "Your login ID is" msgstr "Ваш логин для входа" -#: ../../Zotlabs/Module/Regate.php:340 +#: ../../Zotlabs/Module/Regate.php:360 msgid "" "After your account has been approved by our administrator you will be able " "to login with your login ID and your provided password." msgstr "После того, как ваша учетная запись будет одобрена нашим администратором, вы сможете войти в систему, указав свой логин и пароль." -#: ../../Zotlabs/Module/Regate.php:352 +#: ../../Zotlabs/Module/Regate.php:372 msgid "Registration request revoked" msgstr "Запрос на регистрацию был отозван" -#: ../../Zotlabs/Module/Regate.php:353 +#: ../../Zotlabs/Module/Regate.php:373 msgid "Sorry for any inconvience. Thank you for your response." msgstr "Приносим извинения за неудобства. Благодарим за ваш ответ." -#: ../../Zotlabs/Module/Regate.php:377 +#: ../../Zotlabs/Module/Regate.php:397 msgid "Please enter your verification token for ID" msgstr "Пожалуйста введите ваш проверочный код для идентификации" -#: ../../Zotlabs/Module/Regate.php:378 ../../Zotlabs/Module/Regate.php:405 +#: ../../Zotlabs/Module/Regate.php:398 ../../Zotlabs/Module/Regate.php:425 msgid "Please check your email!" msgstr "Пожалуйста, проверьте вашу электронную почту!" -#: ../../Zotlabs/Module/Regate.php:388 +#: ../../Zotlabs/Module/Regate.php:408 msgid "Verification token" msgstr "Код проверки" -#: ../../Zotlabs/Module/Regate.php:399 +#: ../../Zotlabs/Module/Regate.php:419 msgid "ID expired" msgstr "Срок действия идентификатора истёк" -#: ../../Zotlabs/Module/Regate.php:414 +#: ../../Zotlabs/Module/Regate.php:434 msgid "You will require the verification token for ID" msgstr "Вам потребуется проверочный кода для идентификации" -#: ../../Zotlabs/Module/Regate.php:423 +#: ../../Zotlabs/Module/Regate.php:443 msgid "Unknown or expired ID" msgstr "Идентификатор неизвестен или с истекшим сроком действия" -#: ../../Zotlabs/Module/Regate.php:434 +#: ../../Zotlabs/Module/Regate.php:454 msgid "dId2 malformed" msgstr "Неверный dId2" -#: ../../Zotlabs/Module/Share.php:104 ../../Zotlabs/Lib/Activity.php:2236 +#: ../../Zotlabs/Module/Share.php:104 ../../Zotlabs/Lib/Activity.php:2308 +#: ../../include/items.php:3322 #, php-format msgid "🔁 Repeated %1$s's %2$s" msgstr "🔁 Повторил %1$s %2$s" @@ -4303,28 +4385,28 @@ msgstr "🔁 Повторил %1$s %2$s" msgid "Post repeated" msgstr "Публикация повторяется" -#: ../../Zotlabs/Module/Impel.php:43 ../../include/bbcode.php:348 +#: ../../Zotlabs/Module/Impel.php:47 ../../include/bbcode.php:348 msgid "webpage" msgstr "веб-страница" -#: ../../Zotlabs/Module/Impel.php:48 ../../include/bbcode.php:354 +#: ../../Zotlabs/Module/Impel.php:52 ../../include/bbcode.php:354 msgid "block" msgstr "заблокировать" -#: ../../Zotlabs/Module/Impel.php:53 ../../include/bbcode.php:351 +#: ../../Zotlabs/Module/Impel.php:57 ../../include/bbcode.php:351 msgid "layout" msgstr "шаблон" -#: ../../Zotlabs/Module/Impel.php:60 ../../include/bbcode.php:357 +#: ../../Zotlabs/Module/Impel.php:64 ../../include/bbcode.php:357 msgid "menu" msgstr "меню" -#: ../../Zotlabs/Module/Impel.php:185 +#: ../../Zotlabs/Module/Impel.php:188 #, php-format msgid "%s element installed" msgstr "%s элемент установлен" -#: ../../Zotlabs/Module/Impel.php:188 +#: ../../Zotlabs/Module/Impel.php:191 #, php-format msgid "%s element installation failed" msgstr "%sустановка элемента неудачна." @@ -4364,13 +4446,13 @@ msgstr "Название шаблона" msgid "Layout Description (Optional)" msgstr "Описание шаблона (необязательно)" -#: ../../Zotlabs/Module/Layouts.php:184 ../../include/text.php:2690 +#: ../../Zotlabs/Module/Layouts.php:184 ../../include/text.php:2718 msgid "Layouts" msgstr "Шаблоны" #: ../../Zotlabs/Module/Layouts.php:186 ../../Zotlabs/Lib/Apps.php:354 #: ../../include/help.php:118 ../../include/help.php:126 -#: ../../include/nav.php:178 ../../include/nav.php:317 +#: ../../include/nav.php:176 ../../include/nav.php:315 msgid "Help" msgstr "Помощь" @@ -4407,7 +4489,7 @@ msgid "Bookmark added" msgstr "Закладка добавлена" #: ../../Zotlabs/Module/Bookmarks.php:90 ../../Zotlabs/Lib/Apps.php:335 -#: ../../include/nav.php:495 +#: ../../include/nav.php:493 msgid "Bookmarks" msgstr "Закладки" @@ -4415,12 +4497,13 @@ msgstr "Закладки" msgid "My Connections Bookmarks" msgstr "Закладки моих контактов" -#: ../../Zotlabs/Module/Defperms.php:68 ../../Zotlabs/Module/Connedit.php:90 +#: ../../Zotlabs/Module/Defperms.php:67 ../../Zotlabs/Module/Contactedit.php:78 +#: ../../Zotlabs/Module/Connedit.php:80 msgid "Could not access contact record." msgstr "Не удалось получить доступ к записи контакта." -#: ../../Zotlabs/Module/Defperms.php:112 -#: ../../Zotlabs/Module/Settings/Channel.php:269 +#: ../../Zotlabs/Module/Defperms.php:111 +#: ../../Zotlabs/Module/Settings/Channel.php:146 #: ../../extend/addon/hzaddons/twitter/twitter.php:493 #: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:82 #: ../../extend/addon/hzaddons/piwik/piwik.php:116 @@ -4432,63 +4515,59 @@ msgstr "Не удалось получить доступ к записи кон msgid "Settings updated." msgstr "Настройки обновлены." -#: ../../Zotlabs/Module/Defperms.php:253 ../../Zotlabs/Module/Connedit.php:852 +#: ../../Zotlabs/Module/Defperms.php:252 msgid "Connection Default Permissions" msgstr "Разрешения по умолчанию для контакта" -#: ../../Zotlabs/Module/Defperms.php:254 ../../Zotlabs/Module/Connedit.php:853 +#: ../../Zotlabs/Module/Defperms.php:253 msgid "Apply these permissions automatically" msgstr "Применить эти разрешения автоматически" -#: ../../Zotlabs/Module/Defperms.php:254 -#: ../../Zotlabs/Module/Settings/Channel.php:474 +#: ../../Zotlabs/Module/Defperms.php:253 msgid "" "If enabled, connection requests will be approved without your interaction" msgstr "Если включено, запросы контактов будут одобрены без вашего участия" -#: ../../Zotlabs/Module/Defperms.php:255 ../../Zotlabs/Module/Connedit.php:854 +#: ../../Zotlabs/Module/Defperms.php:254 msgid "Permission role" msgstr "Роль разрешения" -#: ../../Zotlabs/Module/Defperms.php:255 +#: ../../Zotlabs/Module/Defperms.php:254 #: ../../Zotlabs/Module/New_channel.php:157 #: ../../Zotlabs/Module/New_channel.php:164 -#: ../../Zotlabs/Module/Connedit.php:854 #: ../../Zotlabs/Widget/Notifications.php:166 -#: ../../Zotlabs/Widget/Messages.php:28 ../../include/nav.php:321 +#: ../../Zotlabs/Widget/Messages.php:28 ../../include/nav.php:319 msgid "Loading" msgstr "Загрузка" -#: ../../Zotlabs/Module/Defperms.php:256 ../../Zotlabs/Module/Connedit.php:855 +#: ../../Zotlabs/Module/Defperms.php:255 msgid "Add permission role" msgstr "Добавить роль разрешения" -#: ../../Zotlabs/Module/Defperms.php:260 ../../Zotlabs/Module/Connedit.php:868 +#: ../../Zotlabs/Module/Defperms.php:259 ../../Zotlabs/Module/Connedit.php:700 msgid "" "The permissions indicated on this page will be applied to all new " "connections." msgstr "Разрешения, указанные на этой странице, будут применяться ко всем новым соединениям." -#: ../../Zotlabs/Module/Defperms.php:261 +#: ../../Zotlabs/Module/Defperms.php:260 msgid "Automatic approval settings" msgstr "Настройки автоматического одобрения" -#: ../../Zotlabs/Module/Defperms.php:263 ../../Zotlabs/Module/Permcats.php:122 -#: ../../Zotlabs/Module/Connedit.php:888 ../../Zotlabs/Module/Tokens.php:181 +#: ../../Zotlabs/Module/Defperms.php:262 ../../Zotlabs/Module/Permcats.php:238 +#: ../../Zotlabs/Module/Connedit.php:713 msgid "inherited" msgstr "наследуется" -#: ../../Zotlabs/Module/Defperms.php:265 ../../Zotlabs/Module/Permcats.php:120 -#: ../../Zotlabs/Module/Connedit.php:893 ../../Zotlabs/Module/Tokens.php:179 +#: ../../Zotlabs/Module/Defperms.php:264 msgid "My Settings" msgstr "Мои настройки" -#: ../../Zotlabs/Module/Defperms.php:268 ../../Zotlabs/Module/Permcats.php:125 -#: ../../Zotlabs/Module/Connedit.php:895 ../../Zotlabs/Module/Tokens.php:184 +#: ../../Zotlabs/Module/Defperms.php:267 ../../Zotlabs/Module/Connedit.php:720 msgid "Individual Permissions" msgstr "Индивидуальные разрешения" -#: ../../Zotlabs/Module/Defperms.php:269 +#: ../../Zotlabs/Module/Defperms.php:268 msgid "" "Some individual permissions may have been preset or locked based on your " "channel type and privacy settings." @@ -4552,11 +4631,11 @@ msgstr "Рекомендации каналов" msgid "Documentation Search" msgstr "Поиск документации" -#: ../../Zotlabs/Module/Help.php:83 ../../include/nav.php:439 +#: ../../Zotlabs/Module/Help.php:83 ../../include/nav.php:437 msgid "About" msgstr "О себе" -#: ../../Zotlabs/Module/Help.php:84 ../../Zotlabs/Module/Group.php:154 +#: ../../Zotlabs/Module/Help.php:84 ../../Zotlabs/Module/Group.php:173 msgid "Members" msgstr "Участники" @@ -4634,35 +4713,63 @@ msgstr "Показать URL этого файла" msgid "Show in your contacts shared folder" msgstr "Показать общий каталог в ваших контактах" -#: ../../Zotlabs/Module/Permcats.php:29 +#: ../../Zotlabs/Module/Permcats.php:56 +msgid "Contact role deleted." +msgstr "Роль контакта удалена." + +#: ../../Zotlabs/Module/Permcats.php:82 msgid "Permission category name is required." msgstr "Требуется категория разрешений." -#: ../../Zotlabs/Module/Permcats.php:48 -msgid "Permission category saved." -msgstr "Категория разрешения сохранена." +#: ../../Zotlabs/Module/Permcats.php:98 ../../Zotlabs/Module/Permcats.php:123 +msgid "Contact role saved." +msgstr "Роль контакта сохранена." -#: ../../Zotlabs/Module/Permcats.php:78 -msgid "" -"Use this form to create permission rules for various classes of people or " -"connections." -msgstr "Используйте эту форму для создания правил разрешений для различных групп людей и контактов." +#: ../../Zotlabs/Module/Permcats.php:188 +msgid "Role to assign affected contacts and default role to" +msgstr "Назначить роль выбранных контактов и роль по умолчанию для" -#: ../../Zotlabs/Module/Permcats.php:111 ../../Zotlabs/Lib/Apps.php:380 -msgid "Permission Categories" -msgstr "Категории разрешений" +#: ../../Zotlabs/Module/Permcats.php:188 +msgid "Role to assign affected contacts to" +msgstr "Назначить роль выбранных контактов для" + +#: ../../Zotlabs/Module/Permcats.php:219 +msgid "Assign this role to" +msgstr "Назначить эту роль для" + +#: ../../Zotlabs/Module/Permcats.php:221 +msgid "All my contacts" +msgstr "Все мои контакты" + +#: ../../Zotlabs/Module/Permcats.php:232 +msgid "Automatically assign this role to new contacts" +msgstr "Автоматически назначать эту роль для новых контактов" + +#: ../../Zotlabs/Module/Permcats.php:233 +msgid "Contact Roles" +msgstr "Роли контактов" + +#: ../../Zotlabs/Module/Permcats.php:234 +msgid "Role name" +msgstr "Наименование роли" + +#: ../../Zotlabs/Module/Permcats.php:234 +msgid "System role - not editable" +msgstr "Системная роль (не редактируется)" + +#: ../../Zotlabs/Module/Permcats.php:235 +msgid "Deleting" +msgstr "Удаляем" -#: ../../Zotlabs/Module/Permcats.php:119 -msgid "Permission category name" -msgstr "Наименование категории разрешений" +#: ../../Zotlabs/Module/Permcats.php:240 +msgid "Role Permissions" +msgstr "Разрешения роли" -#: ../../Zotlabs/Module/Permcats.php:126 ../../Zotlabs/Module/Connedit.php:896 -#: ../../Zotlabs/Module/Tokens.php:185 +#: ../../Zotlabs/Module/Permcats.php:241 msgid "" -"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " -"individual settings. You can not change those settings here." -msgstr "Некоторые разрешения могут наследовать из настроек приватности ваших каналов которые могут иметь более высокий приоритет чем индивидуальные. Вы не можете менять эти настройки здесь." +"Some permissions may be inherited from your channel " +"role, which have higher priority than contact role settings." +msgstr "Некоторые разрешения могут быть унаследованы от вашей роли канала, которые имеют более высокий приоритет, чем настройки роли контакта." #: ../../Zotlabs/Module/Editblock.php:113 ../../Zotlabs/Module/Blocks.php:97 #: ../../Zotlabs/Module/Blocks.php:155 @@ -4677,20 +4784,20 @@ msgstr "Редактировать блок" msgid "Post not found." msgstr "Публикация не найдена" -#: ../../Zotlabs/Module/Tagger.php:75 ../../Zotlabs/Module/Like.php:441 +#: ../../Zotlabs/Module/Tagger.php:75 ../../Zotlabs/Module/Like.php:447 #: ../../Zotlabs/Module/Channel_calendar.php:221 ../../include/event.php:1259 -#: ../../include/conversation.php:132 ../../include/text.php:2254 +#: ../../include/conversation.php:132 ../../include/text.php:2282 msgid "event" msgstr "событие" -#: ../../Zotlabs/Module/Tagger.php:79 ../../Zotlabs/Lib/Activity.php:3306 +#: ../../Zotlabs/Module/Tagger.php:79 ../../Zotlabs/Lib/Activity.php:3389 #: ../../include/conversation.php:158 ../../include/bbcode.php:555 -#: ../../include/markdown.php:205 ../../include/text.php:2257 +#: ../../include/markdown.php:205 ../../include/text.php:2285 msgid "post" msgstr "публикация" #: ../../Zotlabs/Module/Tagger.php:81 ../../include/conversation.php:160 -#: ../../include/text.php:2259 +#: ../../include/text.php:2287 msgid "comment" msgstr "комментарий" @@ -4755,14 +4862,14 @@ msgstr "Я на связи" msgid "Bookmark this room" msgstr "Запомнить эту комнату" -#: ../../Zotlabs/Module/Chat.php:216 ../../include/conversation.php:1385 +#: ../../Zotlabs/Module/Chat.php:216 ../../include/conversation.php:1399 #: ../../extend/addon/hzaddons/hsse/hsse.php:134 #: ../../extend/addon/hzaddons/mail/Mod_Mail.php:135 msgid "Please enter a link URL:" msgstr "Пожалуйста введите URL ссылки:" -#: ../../Zotlabs/Module/Chat.php:217 ../../Zotlabs/Lib/ThreadItem.php:841 -#: ../../include/conversation.php:1516 +#: ../../Zotlabs/Module/Chat.php:217 ../../Zotlabs/Lib/ThreadItem.php:864 +#: ../../include/conversation.php:1530 #: ../../extend/addon/hzaddons/hsse/hsse.php:255 #: ../../extend/addon/hzaddons/mail/Mod_Mail.php:211 msgid "Encrypt text" @@ -4801,7 +4908,7 @@ msgstr "Срок действия" msgid "min" msgstr "мин." -#: ../../Zotlabs/Module/Blocks.php:154 ../../include/text.php:2688 +#: ../../Zotlabs/Module/Blocks.php:154 ../../include/text.php:2716 msgid "Blocks" msgstr "Блокировки" @@ -4809,6 +4916,88 @@ msgstr "Блокировки" msgid "Block Title" msgstr "Заблокировать заголовок" +#: ../../Zotlabs/Module/Settings/Privacy.php:39 +msgid "Privacy settings updated." +msgstr "Настройки конфиденциальности обновлены." + +#: ../../Zotlabs/Module/Settings/Privacy.php:56 +#: ../../Zotlabs/Lib/PermissionDescription.php:107 +#: ../../include/acl_selectors.php:136 +msgid "Only me" +msgstr "Только мне" + +#: ../../Zotlabs/Module/Settings/Privacy.php:57 +msgid "Only those you specifically allow" +msgstr "Только персонально разрешённые" + +#: ../../Zotlabs/Module/Settings/Privacy.php:58 +msgid "Approved connections" +msgstr "Одобренные контакты" + +#: ../../Zotlabs/Module/Settings/Privacy.php:59 +msgid "Any connections" +msgstr "Любые контакты" + +#: ../../Zotlabs/Module/Settings/Privacy.php:60 +msgid "Anybody on this website" +msgstr "Любой на этом сайте" + +#: ../../Zotlabs/Module/Settings/Privacy.php:61 +msgid "Anybody in this network" +msgstr "Любой в этой сети" + +#: ../../Zotlabs/Module/Settings/Privacy.php:62 +msgid "Anybody authenticated" +msgstr "Любой аутентифицированный" + +#: ../../Zotlabs/Module/Settings/Privacy.php:63 +msgid "Anybody on the internet" +msgstr "Любой в интернете" + +#: ../../Zotlabs/Module/Settings/Privacy.php:73 +msgid "" +"Advise: set to \"Anybody on the internet\" and use privacy groups to " +"restrict access" +msgstr "Совет: установите значение «Кто угодно в Интернете» и используйте группы конфиденциальности для ограничения доступа." + +#: ../../Zotlabs/Module/Settings/Privacy.php:109 +msgid "Privacy Settings" +msgstr "Настройки конфиденциальности" + +#: ../../Zotlabs/Module/Settings/Privacy.php:114 +msgid "Advanced configuration" +msgstr "Расширенная конфигурация" + +#: ../../Zotlabs/Module/Settings/Privacy.php:116 +msgid "Proceed with caution" +msgstr "Применять с осторожностью" + +#: ../../Zotlabs/Module/Settings/Privacy.php:117 +msgid "" +"Changing advanced configuration settings can impact your, and your contacts " +"channels functionality and security." +msgstr "Изменение дополнительных параметров конфигурации может повлиять на работу и безопасность ваших каналов и контактов." + +#: ../../Zotlabs/Module/Settings/Privacy.php:118 +msgid "Accept the risk and continue" +msgstr "Принять риск и продолжить" + +#: ../../Zotlabs/Module/Settings/Privacy.php:120 +msgid "Automatically approve new contacts" +msgstr "Автоматически одобрять новые контакты" + +#: ../../Zotlabs/Module/Settings/Privacy.php:121 +msgid "Opt-out of search engine indexing" +msgstr "Исключить из индексирования поисковых систем" + +#: ../../Zotlabs/Module/Settings/Privacy.php:122 +msgid "Group actor" +msgstr "Представление группы" + +#: ../../Zotlabs/Module/Settings/Privacy.php:122 +msgid "Allow this channel to act as a forum" +msgstr "Разрешить выступать этому каналу в качестве форума" + #: ../../Zotlabs/Module/Settings/Directory.php:40 msgid "Directory Settings" msgstr "Настройки каталога" @@ -5011,433 +5200,284 @@ msgstr "Настройки главной страницы канала" msgid "Profiles Settings" msgstr "Настройки профилей" -#: ../../Zotlabs/Module/Settings/Channel.php:71 -#: ../../Zotlabs/Module/Settings/Channel.php:75 -#: ../../Zotlabs/Module/Settings/Channel.php:76 -#: ../../Zotlabs/Module/Settings/Channel.php:79 -#: ../../Zotlabs/Module/Settings/Channel.php:90 -#: ../../Zotlabs/Module/Connedit.php:710 ../../Zotlabs/Widget/Affinity.php:32 -#: ../../include/channel.php:457 ../../include/channel.php:460 -#: ../../include/selectors.php:134 -msgid "Friends" -msgstr "Друзья" - -#: ../../Zotlabs/Module/Settings/Channel.php:331 -msgid "Nobody except yourself" -msgstr "Никто кроме вас" - -#: ../../Zotlabs/Module/Settings/Channel.php:332 -msgid "Only those you specifically allow" -msgstr "Только персонально разрешённые" - -#: ../../Zotlabs/Module/Settings/Channel.php:333 -msgid "Approved connections" -msgstr "Одобренные контакты" - -#: ../../Zotlabs/Module/Settings/Channel.php:334 -msgid "Any connections" -msgstr "Любые контакты" - -#: ../../Zotlabs/Module/Settings/Channel.php:335 -msgid "Anybody on this website" -msgstr "Любой на этом сайте" - -#: ../../Zotlabs/Module/Settings/Channel.php:336 -msgid "Anybody in this network" -msgstr "Любой в этой сети" - -#: ../../Zotlabs/Module/Settings/Channel.php:337 -msgid "Anybody authenticated" -msgstr "Любой аутентифицированный" - -#: ../../Zotlabs/Module/Settings/Channel.php:338 -msgid "Anybody on the internet" -msgstr "Любой в интернете" - -#: ../../Zotlabs/Module/Settings/Channel.php:413 -msgid "Publish your default profile in the network directory" -msgstr "Публиковать ваш профиль по умолчанию в сетевом каталоге" - -#: ../../Zotlabs/Module/Settings/Channel.php:418 -msgid "Allow us to suggest you as a potential friend to new members?" -msgstr "Разрешить предлагать вас как потенциального друга для новых пользователей?" +#: ../../Zotlabs/Module/Settings/Channel.php:103 +#: ../../Zotlabs/Module/Settings/Channel.php:212 +msgid "Please select a channel role" +msgstr "Пожалуйста, выберите роль канала" -#: ../../Zotlabs/Module/Settings/Channel.php:431 +#: ../../Zotlabs/Module/Settings/Channel.php:189 msgid "Your channel address is" msgstr "Адрес вашего канала" -#: ../../Zotlabs/Module/Settings/Channel.php:434 +#: ../../Zotlabs/Module/Settings/Channel.php:192 msgid "Your files/photos are accessible via WebDAV at" msgstr "Ваши файлы / фотографии доступны через WebDAV по" -#: ../../Zotlabs/Module/Settings/Channel.php:474 -msgid "Automatic membership approval" -msgstr "Членство одобрено автоматически" - -#: ../../Zotlabs/Module/Settings/Channel.php:497 +#: ../../Zotlabs/Module/Settings/Channel.php:223 msgid "Channel Settings" msgstr "Настройки канала" -#: ../../Zotlabs/Module/Settings/Channel.php:504 +#: ../../Zotlabs/Module/Settings/Channel.php:228 +#: ../../Zotlabs/Module/New_channel.php:178 +msgid "Channel role" +msgstr "Роль канала" + +#: ../../Zotlabs/Module/Settings/Channel.php:230 msgid "Basic Settings" msgstr "Основные настройки" -#: ../../Zotlabs/Module/Settings/Channel.php:505 ../../include/channel.php:1721 -msgid "Full Name:" -msgstr "Полное имя:" - -#: ../../Zotlabs/Module/Settings/Channel.php:506 -msgid "Email Address:" -msgstr "Адрес email:" +#: ../../Zotlabs/Module/Settings/Channel.php:231 +msgid "Channel timezone:" +msgstr "Часовой пояс канала:" -#: ../../Zotlabs/Module/Settings/Channel.php:507 -msgid "Your Timezone:" -msgstr "Часовой пояс:" - -#: ../../Zotlabs/Module/Settings/Channel.php:508 -msgid "Default Post Location:" -msgstr "Расположение по умолчанию:" +#: ../../Zotlabs/Module/Settings/Channel.php:232 +msgid "Default post location:" +msgstr "Местоположение публикации по умолчанию:" -#: ../../Zotlabs/Module/Settings/Channel.php:508 +#: ../../Zotlabs/Module/Settings/Channel.php:232 msgid "Geographical location to display on your posts" msgstr "Показывать географическое положение в ваших публикациях" -#: ../../Zotlabs/Module/Settings/Channel.php:509 -msgid "Use Browser Location:" -msgstr "Определять расположение из браузера" +#: ../../Zotlabs/Module/Settings/Channel.php:233 +msgid "Use browser location:" +msgstr "Использовать данные о местоположении браузера:" -#: ../../Zotlabs/Module/Settings/Channel.php:511 +#: ../../Zotlabs/Module/Settings/Channel.php:234 msgid "Adult Content" msgstr "Содержимое для взрослых" -#: ../../Zotlabs/Module/Settings/Channel.php:511 -msgid "" -"This channel frequently or regularly publishes adult content. (Please tag " -"any adult material and/or nudity with #NSFW)" -msgstr "Этот канал часто или регулярно публикует содержимое для взрослых. Пожалуйста, помечайте любой такой материал тегом #NSFW" - -#: ../../Zotlabs/Module/Settings/Channel.php:513 -msgid "Security and Privacy Settings" -msgstr "Безопасность и настройки приватности" +#: ../../Zotlabs/Module/Settings/Channel.php:234 +msgid "This channel frequently or regularly publishes adult content" +msgstr "На этом канале часто или регулярно публикуется контент для взрослых" -#: ../../Zotlabs/Module/Settings/Channel.php:515 -msgid "Your permissions are already configured. Click to view/adjust" -msgstr "Ваши разрешения уже настроены. Нажмите чтобы просмотреть или изменить" +#: ../../Zotlabs/Module/Settings/Channel.php:235 +msgid "Maximum Friend Requests/Day:" +msgstr "Запросов в друзья в день:" -#: ../../Zotlabs/Module/Settings/Channel.php:517 -msgid "Hide my online presence" -msgstr "Скрывать моё присутствие онлайн" +#: ../../Zotlabs/Module/Settings/Channel.php:235 +msgid "May reduce spam activity" +msgstr "Может ограничить спам активность" -#: ../../Zotlabs/Module/Settings/Channel.php:517 -msgid "Prevents displaying in your profile that you are online" -msgstr "Предотвращает отображения статуса \"в сети\" в вашем профиле" +#: ../../Zotlabs/Module/Settings/Channel.php:236 +#: ../../Zotlabs/Lib/Enotify.php:68 +msgid "Notification Settings" +msgstr "Настройки уведомлений" -#: ../../Zotlabs/Module/Settings/Channel.php:519 -msgid "Simple Privacy Settings:" -msgstr "Простые настройки безопасности:" +#: ../../Zotlabs/Module/Settings/Channel.php:237 +msgid "By default post a status message when:" +msgstr "По умолчанию публиковать новый статус при:" -#: ../../Zotlabs/Module/Settings/Channel.php:520 -msgid "" -"Very Public - extremely permissive (should be used with caution)" -msgstr "Полностью открытый - сверхлиберальный (должен использоваться с осторожностью)" +#: ../../Zotlabs/Module/Settings/Channel.php:238 +msgid "accepting a friend request" +msgstr "одобрении запроса в друзья" -#: ../../Zotlabs/Module/Settings/Channel.php:521 -msgid "" -"Typical - default public, privacy when desired (similar to social " -"network permissions but with improved privacy)" -msgstr "Обычный - открытый по умолчанию, приватность по желанию (как в социальных сетях, но с улучшенными настройками)" +#: ../../Zotlabs/Module/Settings/Channel.php:239 +msgid "joining a forum/community" +msgstr "вступлении в сообщество / форум" -#: ../../Zotlabs/Module/Settings/Channel.php:522 -msgid "Private - default private, never open or public" -msgstr "Частный - частный по умочанию, не открытый и не публичный" +#: ../../Zotlabs/Module/Settings/Channel.php:240 +msgid "making an interesting profile change" +msgstr "интересном изменении профиля" -#: ../../Zotlabs/Module/Settings/Channel.php:523 -msgid "Blocked - default blocked to/from everybody" -msgstr "Закрытый - заблокированный по умолчанию от / для всех" +#: ../../Zotlabs/Module/Settings/Channel.php:241 +msgid "Send a notification email when:" +msgstr "Отправить уведомление по email когда:" -#: ../../Zotlabs/Module/Settings/Channel.php:525 -msgid "Allow others to tag your posts" -msgstr "Разрешить другим отмечать ваши публикации" +#: ../../Zotlabs/Module/Settings/Channel.php:242 +msgid "You receive a connection request" +msgstr "вы получили новый запрос контакта" -#: ../../Zotlabs/Module/Settings/Channel.php:525 -msgid "" -"Often used by the community to retro-actively flag inappropriate content" -msgstr "Часто используется сообществом для маркировки неподобающего содержания" +#: ../../Zotlabs/Module/Settings/Channel.php:243 +msgid "Your connections are confirmed" +msgstr "Ваш запрос контакта был одобрен" -#: ../../Zotlabs/Module/Settings/Channel.php:527 -msgid "Channel Permission Limits" -msgstr "Ограничения разрешений канала" - -#: ../../Zotlabs/Module/Settings/Channel.php:529 -msgid "Expire other channel content after this many days" -msgstr "Храненить содержимое других каналов, дней" - -#: ../../Zotlabs/Module/Settings/Channel.php:529 -msgid "0 or blank to use the website limit." -msgstr "0 или пусто - использовать настройки сайта." - -#: ../../Zotlabs/Module/Settings/Channel.php:529 -#, php-format -msgid "This website expires after %d days." -msgstr "Срок хранения содержимого этого сайта истекает через %d дней" - -#: ../../Zotlabs/Module/Settings/Channel.php:529 -msgid "This website does not expire imported content." -msgstr "Срок хранения импортированного содержимого этого сайта не ограничен." - -#: ../../Zotlabs/Module/Settings/Channel.php:529 -msgid "The website limit takes precedence if lower than your limit." -msgstr "Ограничение сайта имеет приоритет если ниже вашего значения." - -#: ../../Zotlabs/Module/Settings/Channel.php:530 -msgid "Maximum Friend Requests/Day:" -msgstr "Запросов в друзья в день:" - -#: ../../Zotlabs/Module/Settings/Channel.php:530 -msgid "May reduce spam activity" -msgstr "Может ограничить спам активность" - -#: ../../Zotlabs/Module/Settings/Channel.php:531 -msgid "Default Privacy Group" -msgstr "Группа конфиденциальности по умолчанию" - -#: ../../Zotlabs/Module/Settings/Channel.php:532 -#: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247 -msgid "(click to open/close)" -msgstr "(нажмите чтобы открыть/закрыть)" - -#: ../../Zotlabs/Module/Settings/Channel.php:533 -msgid "Use my default audience setting for the type of object published" -msgstr "Использовать настройки аудитории по умолчанию для типа опубликованного объекта" - -#: ../../Zotlabs/Module/Settings/Channel.php:541 -#: ../../Zotlabs/Module/New_channel.php:178 -msgid "Channel role and privacy" -msgstr "Роль и конфиденциальность канала" - -#: ../../Zotlabs/Module/Settings/Channel.php:542 -msgid "Default permissions category" -msgstr "Категория разрешений по умолчанию" - -#: ../../Zotlabs/Module/Settings/Channel.php:548 -msgid "Maximum private messages per day from unknown people:" -msgstr "Максимально количество сообщений от незнакомых людей, в день:" - -#: ../../Zotlabs/Module/Settings/Channel.php:548 -msgid "Useful to reduce spamming" -msgstr "Полезно для сокращения количества спама" - -#: ../../Zotlabs/Module/Settings/Channel.php:551 -#: ../../Zotlabs/Lib/Enotify.php:68 -msgid "Notification Settings" -msgstr "Настройки уведомлений" - -#: ../../Zotlabs/Module/Settings/Channel.php:552 -msgid "By default post a status message when:" -msgstr "По умолчанию публиковать новый статус при:" - -#: ../../Zotlabs/Module/Settings/Channel.php:553 -msgid "accepting a friend request" -msgstr "одобрении запроса в друзья" - -#: ../../Zotlabs/Module/Settings/Channel.php:554 -msgid "joining a forum/community" -msgstr "вступлении в сообщество / форум" - -#: ../../Zotlabs/Module/Settings/Channel.php:555 -msgid "making an interesting profile change" -msgstr "интересном изменении профиля" - -#: ../../Zotlabs/Module/Settings/Channel.php:556 -msgid "Send a notification email when:" -msgstr "Отправить уведомление по email когда:" - -#: ../../Zotlabs/Module/Settings/Channel.php:557 -msgid "You receive a connection request" -msgstr "вы получили новый запрос контакта" - -#: ../../Zotlabs/Module/Settings/Channel.php:558 -msgid "Your connections are confirmed" -msgstr "Ваш запрос контакта был одобрен" - -#: ../../Zotlabs/Module/Settings/Channel.php:559 +#: ../../Zotlabs/Module/Settings/Channel.php:244 msgid "Someone writes on your profile wall" msgstr "Кто-то написал на стене вашего профиля" -#: ../../Zotlabs/Module/Settings/Channel.php:560 +#: ../../Zotlabs/Module/Settings/Channel.php:245 msgid "Someone writes a followup comment" msgstr "Кто-то пишет комментарий" -#: ../../Zotlabs/Module/Settings/Channel.php:561 +#: ../../Zotlabs/Module/Settings/Channel.php:246 msgid "You receive a private message" msgstr "Вы получили личное сообщение" -#: ../../Zotlabs/Module/Settings/Channel.php:562 +#: ../../Zotlabs/Module/Settings/Channel.php:247 msgid "You receive a friend suggestion" msgstr "Вы получили предложение друзей" -#: ../../Zotlabs/Module/Settings/Channel.php:563 +#: ../../Zotlabs/Module/Settings/Channel.php:248 msgid "You are tagged in a post" msgstr "Вы были отмечены в публикации" -#: ../../Zotlabs/Module/Settings/Channel.php:564 +#: ../../Zotlabs/Module/Settings/Channel.php:249 msgid "You are poked/prodded/etc. in a post" msgstr "Вас толкнули, подтолкнули и т.п. в публикации" -#: ../../Zotlabs/Module/Settings/Channel.php:566 +#: ../../Zotlabs/Module/Settings/Channel.php:250 msgid "Someone likes your post/comment" msgstr "Кому-то нравится ваша публикация / комментарий" -#: ../../Zotlabs/Module/Settings/Channel.php:569 +#: ../../Zotlabs/Module/Settings/Channel.php:251 msgid "Show visual notifications including:" msgstr "Показывать визуальные оповещения включая:" -#: ../../Zotlabs/Module/Settings/Channel.php:571 +#: ../../Zotlabs/Module/Settings/Channel.php:252 msgid "Unseen stream activity" msgstr "Новая активность в потоке" -#: ../../Zotlabs/Module/Settings/Channel.php:572 +#: ../../Zotlabs/Module/Settings/Channel.php:253 msgid "Unseen channel activity" msgstr "Новая активность в канале" -#: ../../Zotlabs/Module/Settings/Channel.php:573 +#: ../../Zotlabs/Module/Settings/Channel.php:254 msgid "Unseen private messages" msgstr "Новые личные сообщения" -#: ../../Zotlabs/Module/Settings/Channel.php:573 -#: ../../Zotlabs/Module/Settings/Channel.php:578 -#: ../../Zotlabs/Module/Settings/Channel.php:579 -#: ../../Zotlabs/Module/Settings/Channel.php:580 +#: ../../Zotlabs/Module/Settings/Channel.php:254 +#: ../../Zotlabs/Module/Settings/Channel.php:259 +#: ../../Zotlabs/Module/Settings/Channel.php:260 +#: ../../Zotlabs/Module/Settings/Channel.php:261 msgid "Recommended" msgstr "Рекомендовано" -#: ../../Zotlabs/Module/Settings/Channel.php:574 +#: ../../Zotlabs/Module/Settings/Channel.php:255 msgid "Upcoming events" msgstr "Грядущие события" -#: ../../Zotlabs/Module/Settings/Channel.php:575 +#: ../../Zotlabs/Module/Settings/Channel.php:256 msgid "Events today" msgstr "События сегодня" -#: ../../Zotlabs/Module/Settings/Channel.php:576 +#: ../../Zotlabs/Module/Settings/Channel.php:257 msgid "Upcoming birthdays" msgstr "Грядущие дни рождения" -#: ../../Zotlabs/Module/Settings/Channel.php:576 +#: ../../Zotlabs/Module/Settings/Channel.php:257 msgid "Not available in all themes" msgstr "Не доступно во всех темах" -#: ../../Zotlabs/Module/Settings/Channel.php:577 +#: ../../Zotlabs/Module/Settings/Channel.php:258 msgid "System (personal) notifications" msgstr "Системные (личные) уведомления" -#: ../../Zotlabs/Module/Settings/Channel.php:578 +#: ../../Zotlabs/Module/Settings/Channel.php:259 msgid "System info messages" msgstr "Сообщения с системной информацией" -#: ../../Zotlabs/Module/Settings/Channel.php:579 +#: ../../Zotlabs/Module/Settings/Channel.php:260 msgid "System critical alerts" msgstr "Критические уведомления системы" -#: ../../Zotlabs/Module/Settings/Channel.php:580 +#: ../../Zotlabs/Module/Settings/Channel.php:261 msgid "New connections" msgstr "Новые контакты" -#: ../../Zotlabs/Module/Settings/Channel.php:581 +#: ../../Zotlabs/Module/Settings/Channel.php:262 msgid "System Registrations" msgstr "Системные регистрации" -#: ../../Zotlabs/Module/Settings/Channel.php:582 +#: ../../Zotlabs/Module/Settings/Channel.php:263 msgid "Unseen shared files" msgstr "Новые общие файлы" -#: ../../Zotlabs/Module/Settings/Channel.php:583 +#: ../../Zotlabs/Module/Settings/Channel.php:264 msgid "Unseen public stream activity" msgstr "Новая активность в публичном потоке" -#: ../../Zotlabs/Module/Settings/Channel.php:584 +#: ../../Zotlabs/Module/Settings/Channel.php:265 msgid "Unseen likes and dislikes" msgstr "Новые лайки и дислайки" -#: ../../Zotlabs/Module/Settings/Channel.php:585 +#: ../../Zotlabs/Module/Settings/Channel.php:266 msgid "Unseen forum posts" msgstr "Новые публикации на форуме" -#: ../../Zotlabs/Module/Settings/Channel.php:586 +#: ../../Zotlabs/Module/Settings/Channel.php:267 msgid "Email notification hub (hostname)" msgstr "Центр уведомлений по email (имя хоста)" -#: ../../Zotlabs/Module/Settings/Channel.php:586 +#: ../../Zotlabs/Module/Settings/Channel.php:267 #, php-format msgid "" "If your channel is mirrored to multiple hubs, set this to your preferred " "location. This will prevent duplicate email notifications. Example: %s" msgstr "Если ваш канал зеркалируется в нескольких местах, это ваше предпочтительное местоположение. Это должно предотвратить дублировать уведомлений по email. Например: %s" -#: ../../Zotlabs/Module/Settings/Channel.php:587 +#: ../../Zotlabs/Module/Settings/Channel.php:268 msgid "Show new wall posts, private messages and connections under Notices" msgstr "Показать новые сообщения на стене, личные сообщения и контакты в \"Уведомлениях\"" -#: ../../Zotlabs/Module/Settings/Channel.php:588 +#: ../../Zotlabs/Module/Settings/Channel.php:269 msgid "Mark all notices of the thread read if a notice is clicked" msgstr "Отметить все уведомления цепочки как прочитанные при нажатии" -#: ../../Zotlabs/Module/Settings/Channel.php:588 +#: ../../Zotlabs/Module/Settings/Channel.php:269 msgid "If no, only the clicked notice will be marked read" msgstr "Если выключено, только одно уведомление будет помечено как прочитанное" -#: ../../Zotlabs/Module/Settings/Channel.php:589 +#: ../../Zotlabs/Module/Settings/Channel.php:270 msgid "" "Desktop notifications are unavailable because the required browser " "permission has not been granted" msgstr "Уведомления на рабочем столе недоступны, поскольку не предоставлено необходимое разрешение от браузера." -#: ../../Zotlabs/Module/Settings/Channel.php:590 +#: ../../Zotlabs/Module/Settings/Channel.php:271 msgid "Grant permission" msgstr "Предоставить разрешение" -#: ../../Zotlabs/Module/Settings/Channel.php:591 +#: ../../Zotlabs/Module/Settings/Channel.php:272 msgid "Notify me of events this many days in advance" msgstr "Уведомлять меня о событиях заранее, дней" -#: ../../Zotlabs/Module/Settings/Channel.php:591 +#: ../../Zotlabs/Module/Settings/Channel.php:272 msgid "Must be greater than 0" msgstr "Должно быть больше 0" -#: ../../Zotlabs/Module/Settings/Channel.php:596 -msgid "Advanced Account/Page Type Settings" -msgstr "Дополнительные настройки учётной записи / страницы" - -#: ../../Zotlabs/Module/Settings/Channel.php:597 -msgid "Change the behaviour of this account for special situations" -msgstr "Изменить поведение этого аккаунта в особых ситуациях" - -#: ../../Zotlabs/Module/Settings/Channel.php:599 -msgid "Miscellaneous Settings" -msgstr "Дополнительные настройки" - -#: ../../Zotlabs/Module/Settings/Channel.php:600 +#: ../../Zotlabs/Module/Settings/Channel.php:275 msgid "Default photo upload folder" msgstr "Каталог загрузки фотографий по умолчанию" -#: ../../Zotlabs/Module/Settings/Channel.php:600 -#: ../../Zotlabs/Module/Settings/Channel.php:601 +#: ../../Zotlabs/Module/Settings/Channel.php:275 +#: ../../Zotlabs/Module/Settings/Channel.php:276 msgid "%Y - current year, %m - current month" msgstr "%Y - текущий год, %y - текущий месяц" -#: ../../Zotlabs/Module/Settings/Channel.php:601 +#: ../../Zotlabs/Module/Settings/Channel.php:276 msgid "Default file upload folder" msgstr "Каталог загрузки файлов по умолчанию" -#: ../../Zotlabs/Module/Settings/Channel.php:602 +#: ../../Zotlabs/Module/Settings/Channel.php:277 #: ../../Zotlabs/Module/Removeme.php:64 msgid "Remove Channel" msgstr "Удаление канала" -#: ../../Zotlabs/Module/Settings/Channel.php:603 +#: ../../Zotlabs/Module/Settings/Channel.php:278 msgid "Remove this channel." msgstr "Удалить этот канал." +#: ../../Zotlabs/Module/Settings/Channel.php:279 +msgid "Expire other channel content after this many days" +msgstr "Храненить содержимое других каналов, дней" + +#: ../../Zotlabs/Module/Settings/Channel.php:279 +msgid "0 or blank to use the website limit." +msgstr "0 или пусто - использовать настройки сайта." + +#: ../../Zotlabs/Module/Settings/Channel.php:279 +#, php-format +msgid "This website expires after %d days." +msgstr "Срок хранения содержимого этого сайта истекает через %d дней" + +#: ../../Zotlabs/Module/Settings/Channel.php:279 +msgid "This website does not expire imported content." +msgstr "Срок хранения импортированного содержимого этого сайта не ограничен." + +#: ../../Zotlabs/Module/Settings/Channel.php:279 +msgid "The website limit takes precedence if lower than your limit." +msgstr "Ограничение сайта имеет приоритет если ниже вашего значения." + #: ../../Zotlabs/Module/Settings/Connections.php:40 msgid "Connections Settings" msgstr "Настройки контактов" @@ -5466,6 +5506,274 @@ msgstr "Неверный ответ." msgid "Response submitted. Updates may not appear instantly." msgstr "Ответ отправлен. Обновления могут отображаться не сразу." +#: ../../Zotlabs/Module/Contactedit.php:50 +msgid "Invalid abook_id" +msgstr "Недействительный abook_id" + +#: ../../Zotlabs/Module/Contactedit.php:107 +#: ../../Zotlabs/Module/Connedit.php:101 +msgid "Could not locate selected profile." +msgstr "Не удалось обнаружить выбранный профиль." + +#: ../../Zotlabs/Module/Contactedit.php:192 +#: ../../Zotlabs/Module/Connedit.php:215 +msgid "is now connected to" +msgstr "теперь подключён к" + +#: ../../Zotlabs/Module/Contactedit.php:252 +#: ../../Zotlabs/Module/Contactedit.php:401 +#: ../../Zotlabs/Module/Connedit.php:701 +msgid "Contact Tools" +msgstr "Инструменты контактов" + +#: ../../Zotlabs/Module/Contactedit.php:295 +#: ../../Zotlabs/Module/Connedit.php:579 ../../Zotlabs/Widget/Affinity.php:30 +msgid "Me" +msgstr "Я" + +#: ../../Zotlabs/Module/Contactedit.php:296 +#: ../../Zotlabs/Module/Connedit.php:580 ../../Zotlabs/Widget/Affinity.php:31 +msgid "Family" +msgstr "Семья" + +#: ../../Zotlabs/Module/Contactedit.php:297 +#: ../../Zotlabs/Module/Connedit.php:581 ../../Zotlabs/Widget/Affinity.php:32 +#: ../../include/channel.php:456 ../../include/channel.php:459 +#: ../../include/selectors.php:134 +msgid "Friends" +msgstr "Друзья" + +#: ../../Zotlabs/Module/Contactedit.php:298 +#: ../../Zotlabs/Module/Connedit.php:582 ../../Zotlabs/Widget/Affinity.php:33 +msgid "Acquaintances" +msgstr "Знакомые" + +#: ../../Zotlabs/Module/Contactedit.php:329 +#: ../../Zotlabs/Module/Connedit.php:622 +msgid "Approve this contact" +msgstr "Утвердить этот контакт" + +#: ../../Zotlabs/Module/Contactedit.php:329 +#: ../../Zotlabs/Module/Connedit.php:622 +msgid "Accept contact to allow communication" +msgstr "Принять контакт, чтобы разрешить общение" + +#: ../../Zotlabs/Module/Contactedit.php:362 +#: ../../Zotlabs/Module/Connedit.php:658 ../../Zotlabs/Module/Tokens.php:269 +msgid "Please select a role for this contact!" +msgstr "Пожалуйста, выберите роль для этого контакта!" + +#: ../../Zotlabs/Module/Contactedit.php:382 +#: ../../Zotlabs/Module/Connedit.php:678 +msgid "This contact is unreachable from this location." +msgstr "Этот контакт недоступен из этого местоположения." + +#: ../../Zotlabs/Module/Contactedit.php:383 +#: ../../Zotlabs/Module/Connedit.php:679 +msgid "This contact may be unreachable from other channel locations." +msgstr "Этот контакт может быть недоступен из других мест размещения канала." + +#: ../../Zotlabs/Module/Contactedit.php:385 +#: ../../Zotlabs/Module/Connedit.php:681 +msgid "Location independence is not supported by their network." +msgstr "Независимое местоположение не поддерживается их сетью." + +#: ../../Zotlabs/Module/Contactedit.php:395 +msgid "View profile" +msgstr "Просмотреть профиль" + +#: ../../Zotlabs/Module/Contactedit.php:408 +msgid "Select a role for this contact" +msgstr "Выбрать роль для этого контакта" + +#: ../../Zotlabs/Module/Contactedit.php:409 +#: ../../Zotlabs/Widget/Permcats.php:80 +msgid "Contact roles" +msgstr "Роли контакта" + +#: ../../Zotlabs/Module/Contactedit.php:420 +#: ../../Zotlabs/Module/Connedit.php:703 +msgid "Slide to adjust your degree of friendship" +msgstr "Прокрутить для настройки степени дружбы" + +#: ../../Zotlabs/Module/Contactedit.php:422 +#: ../../Zotlabs/Module/Connedit.php:705 +msgid "Custom Filter" +msgstr "Настраиваемый фильтр" + +#: ../../Zotlabs/Module/Contactedit.php:423 +#: ../../Zotlabs/Module/Connedit.php:706 +msgid "Only import posts with this text" +msgstr "Импортировать публикации только с этим текстом" + +#: ../../Zotlabs/Module/Contactedit.php:424 +#: ../../Zotlabs/Module/Connedit.php:707 +msgid "Do not import posts with this text" +msgstr "Не импортировать публикации с этим текстом" + +#: ../../Zotlabs/Module/Contactedit.php:429 +#: ../../Zotlabs/Module/Connedit.php:714 +msgid "Approve contact" +msgstr "Утвердить контакт" + +#: ../../Zotlabs/Module/Contactedit.php:431 +#: ../../Zotlabs/Module/Connedit.php:717 +msgid "Their" +msgstr "Их" + +#: ../../Zotlabs/Module/Contactedit.php:432 +#: ../../Zotlabs/Module/Connedit.php:718 +msgid "My" +msgstr "Мои" + +#: ../../Zotlabs/Module/Contactedit.php:449 +msgid "Contact updated" +msgstr "Контакт обновлён" + +#: ../../Zotlabs/Module/Contactedit.php:449 +msgid "Contact update failed" +msgstr "Обновление контакта не удалось" + +#: ../../Zotlabs/Module/Contactedit.php:501 +#: ../../Zotlabs/Module/Contactedit.php:511 +msgid "Refresh succeeded" +msgstr "Обновление выполнено" + +#: ../../Zotlabs/Module/Contactedit.php:504 +msgid "Refresh failed - channel is currently unavailable" +msgstr "Ошибка обновления - канал в настоящее время недоступен" + +#: ../../Zotlabs/Module/Contactedit.php:523 +msgid "Block status updated" +msgstr "Статус блокировки обновлён" + +#: ../../Zotlabs/Module/Contactedit.php:527 +msgid "Block failed" +msgstr "Блокировка не удалась" + +#: ../../Zotlabs/Module/Contactedit.php:538 +msgid "Ignore status updated" +msgstr "Статус игнорирования обновлён" + +#: ../../Zotlabs/Module/Contactedit.php:542 +msgid "Ignore failed" +msgstr "Игнорирование не удалось" + +#: ../../Zotlabs/Module/Contactedit.php:553 +msgid "Archive status updated" +msgstr "Статус архивации обновлён" + +#: ../../Zotlabs/Module/Contactedit.php:557 +msgid "Archive failed" +msgstr "Архивация не удалась" + +#: ../../Zotlabs/Module/Contactedit.php:568 +msgid "Hide status updated" +msgstr "Статус скрытия обновлён" + +#: ../../Zotlabs/Module/Contactedit.php:572 +msgid "Hide failed" +msgstr "Скрытие не удалось" + +#: ../../Zotlabs/Module/Contactedit.php:607 +msgid "Contact removed" +msgstr "Контакт удалён" + +#: ../../Zotlabs/Module/Contactedit.php:611 +msgid "Delete failed" +msgstr "Не удалось удалить" + +#: ../../Zotlabs/Module/Contactedit.php:621 +#: ../../Zotlabs/Module/Connedit.php:487 +msgid "Refresh Permissions" +msgstr "Обновить разрешения" + +#: ../../Zotlabs/Module/Contactedit.php:622 +#: ../../Zotlabs/Module/Connedit.php:490 +msgid "Fetch updated permissions" +msgstr "Получить обновлённые разрешения" + +#: ../../Zotlabs/Module/Contactedit.php:626 +#: ../../Zotlabs/Module/Connedit.php:494 +msgid "Refresh Photo" +msgstr "Обновить фотографию" + +#: ../../Zotlabs/Module/Contactedit.php:627 +#: ../../Zotlabs/Module/Connedit.php:497 +msgid "Fetch updated photo" +msgstr "Получить обновлённую фотографию" + +#: ../../Zotlabs/Module/Contactedit.php:634 +#: ../../Zotlabs/Module/Connedit.php:511 +msgid "Block (or Unblock) all communications with this connection" +msgstr "Блокировать (или разблокировать) связи с этим контактом" + +#: ../../Zotlabs/Module/Contactedit.php:635 +#: ../../Zotlabs/Module/Connedit.php:512 +msgid "This connection is blocked!" +msgstr "Этот контакт заблокирован!" + +#: ../../Zotlabs/Module/Contactedit.php:639 +#: ../../Zotlabs/Module/Connedit.php:516 +msgid "Unignore" +msgstr "Не игнорировать" + +#: ../../Zotlabs/Module/Contactedit.php:641 +#: ../../Zotlabs/Module/Connedit.php:519 +msgid "Ignore (or Unignore) all inbound communications from this connection" +msgstr "Игнорировать (или не игнорировать) все связи для этого контакта" + +#: ../../Zotlabs/Module/Contactedit.php:642 +#: ../../Zotlabs/Module/Connedit.php:520 +msgid "This connection is ignored!" +msgstr "Этот контакт игнорируется!" + +#: ../../Zotlabs/Module/Contactedit.php:646 +#: ../../Zotlabs/Module/Connedit.php:524 +msgid "Unarchive" +msgstr "Разархивировать" + +#: ../../Zotlabs/Module/Contactedit.php:646 +#: ../../Zotlabs/Module/Connedit.php:524 +msgid "Archive" +msgstr "Заархивировать" + +#: ../../Zotlabs/Module/Contactedit.php:648 +#: ../../Zotlabs/Module/Connedit.php:527 +msgid "" +"Archive (or Unarchive) this connection - mark channel dead but keep content" +msgstr "Заархивировать (или разархивировать) этот контакт - пометить канал отключённым но сохранить содержимое" + +#: ../../Zotlabs/Module/Contactedit.php:649 +#: ../../Zotlabs/Module/Connedit.php:528 +msgid "This connection is archived!" +msgstr "Этот контакт заархивирован!" + +#: ../../Zotlabs/Module/Contactedit.php:653 +#: ../../Zotlabs/Module/Connedit.php:532 +msgid "Unhide" +msgstr "Показать" + +#: ../../Zotlabs/Module/Contactedit.php:653 +#: ../../Zotlabs/Module/Connedit.php:532 +msgid "Hide" +msgstr "Скрыть" + +#: ../../Zotlabs/Module/Contactedit.php:655 +#: ../../Zotlabs/Module/Connedit.php:535 +msgid "Hide or Unhide this connection from your other connections" +msgstr "Скрыть или показать этот контакт от / для остальных" + +#: ../../Zotlabs/Module/Contactedit.php:656 +#: ../../Zotlabs/Module/Connedit.php:536 +msgid "This connection is hidden!" +msgstr "Этот контакт скрыт!" + +#: ../../Zotlabs/Module/Contactedit.php:662 +#: ../../Zotlabs/Module/Connedit.php:543 +msgid "Delete this connection" +msgstr "Удалить этот контакт" + #: ../../Zotlabs/Module/Locs.php:27 ../../Zotlabs/Module/Locs.php:65 msgid "Location not found." msgstr "Местоположение не найдено" @@ -5533,7 +5841,7 @@ msgstr "не установлено" msgid "Register is closed" msgstr "Регистрация закрыта" -#: ../../Zotlabs/Module/Invite.php:102 ../../Zotlabs/Module/Invite.php:548 +#: ../../Zotlabs/Module/Invite.php:102 ../../Zotlabs/Module/Invite.php:549 msgid "Note, the invitation code is valid up to" msgstr "Обратите внимание: код приглашения действителен до " @@ -5546,11 +5854,6 @@ msgstr "Слишком много получателей для одного к msgid "No recipients for this invitation" msgstr "Нет получателей для этого приглашения" -#: ../../Zotlabs/Module/Invite.php:133 -#, php-format -msgid "(%s) : Not a valid email address" -msgstr "(%s) : Недействительный адрес электронной почты" - #: ../../Zotlabs/Module/Invite.php:138 #, php-format msgid "(%s) : Not a real email address" @@ -5571,8 +5874,8 @@ msgstr "(%s) : Адрес электронной почты уже исполь msgid "(%s) : Accepted email address" msgstr "%s) : Подтверждённый адрес электронной почты" -#: ../../Zotlabs/Module/Invite.php:225 ../../Zotlabs/Module/Invite.php:493 -#: ../../Zotlabs/Module/Invite.php:507 ../../Zotlabs/Module/Home.php:87 +#: ../../Zotlabs/Module/Invite.php:225 ../../Zotlabs/Module/Invite.php:494 +#: ../../Zotlabs/Module/Invite.php:508 ../../Zotlabs/Module/Home.php:87 #: ../../Zotlabs/Module/Home.php:95 ../../Zotlabs/Lib/Enotify.php:66 #: ../../extend/addon/hzaddons/opensearch/opensearch.php:42 msgid "$Projectname" @@ -5622,44 +5925,44 @@ msgstr "Превышен лимит приглашений для всех по msgid "Invitation expires after" msgstr "Приглашение истекает после" -#: ../../Zotlabs/Module/Invite.php:503 ../../Zotlabs/Module/Invite.php:542 +#: ../../Zotlabs/Module/Invite.php:504 ../../Zotlabs/Module/Invite.php:543 msgid "Invitation" msgstr "Приглашение" -#: ../../Zotlabs/Module/Invite.php:533 +#: ../../Zotlabs/Module/Invite.php:534 msgid "Send invitations" msgstr "Отправить приглашение" -#: ../../Zotlabs/Module/Invite.php:534 +#: ../../Zotlabs/Module/Invite.php:535 msgid "Invitations I am using" msgstr "Приглашения, которые я использую" -#: ../../Zotlabs/Module/Invite.php:535 +#: ../../Zotlabs/Module/Invite.php:536 msgid "Invitations we are using" msgstr "Приглашения, которые мы используем" -#: ../../Zotlabs/Module/Invite.php:536 +#: ../../Zotlabs/Module/Invite.php:537 msgid "§ Note, the email(s) sent will be recorded in the system logs" msgstr "Внимание: адреса электронной почты будут записаны в системные журналы." -#: ../../Zotlabs/Module/Invite.php:537 +#: ../../Zotlabs/Module/Invite.php:538 msgid "Enter email addresses, one per line:" msgstr "Введите адреса электронной почты, по одному в строке:" -#: ../../Zotlabs/Module/Invite.php:538 +#: ../../Zotlabs/Module/Invite.php:539 msgid "Your message:" msgstr "Сообщение:" -#: ../../Zotlabs/Module/Invite.php:539 +#: ../../Zotlabs/Module/Invite.php:540 msgid "Invite template" msgstr "Шаблон приглашения" -#: ../../Zotlabs/Module/Invite.php:541 +#: ../../Zotlabs/Module/Invite.php:542 #: ../../extend/addon/hzaddons/mail/Mod_Mail.php:198 msgid "Subject:" msgstr "Тема:" -#: ../../Zotlabs/Module/Invite.php:547 +#: ../../Zotlabs/Module/Invite.php:548 msgid "Here you may enter personal notes to the recipient(s)" msgstr "Здесь вы можете ввести личные заметки для получателей" @@ -5668,30 +5971,30 @@ msgstr "Здесь вы можете ввести личные заметки д msgid "Cover Photos" msgstr "Фотографии обложки" -#: ../../Zotlabs/Module/Cover_photo.php:297 ../../include/items.php:4630 +#: ../../Zotlabs/Module/Cover_photo.php:297 ../../include/items.php:4762 msgid "female" msgstr "женщина" -#: ../../Zotlabs/Module/Cover_photo.php:298 ../../include/items.php:4631 +#: ../../Zotlabs/Module/Cover_photo.php:298 ../../include/items.php:4763 #, php-format msgid "%1$s updated her %2$s" msgstr "%1$s обновила её %2$s" -#: ../../Zotlabs/Module/Cover_photo.php:299 ../../include/items.php:4632 +#: ../../Zotlabs/Module/Cover_photo.php:299 ../../include/items.php:4764 msgid "male" msgstr "мужчина" -#: ../../Zotlabs/Module/Cover_photo.php:300 ../../include/items.php:4633 +#: ../../Zotlabs/Module/Cover_photo.php:300 ../../include/items.php:4765 #, php-format msgid "%1$s updated his %2$s" msgstr "%1$s обновил его %2$s" -#: ../../Zotlabs/Module/Cover_photo.php:302 ../../include/items.php:4635 +#: ../../Zotlabs/Module/Cover_photo.php:302 ../../include/items.php:4767 #, php-format msgid "%1$s updated their %2$s" msgstr "%2$s %1$s обновлена" -#: ../../Zotlabs/Module/Cover_photo.php:304 ../../include/channel.php:2286 +#: ../../Zotlabs/Module/Cover_photo.php:304 ../../include/channel.php:2335 msgid "cover photo" msgstr "фотография обложки" @@ -5703,23 +6006,23 @@ msgstr "Фотография вашей обложки может быть ви msgid "Change Cover Photo" msgstr "Изменить фотографию обложки" -#: ../../Zotlabs/Module/Network.php:107 +#: ../../Zotlabs/Module/Network.php:106 msgid "No such group" msgstr "Нет такой группы" -#: ../../Zotlabs/Module/Network.php:156 +#: ../../Zotlabs/Module/Network.php:155 msgid "No such channel" msgstr "Нет такого канала" -#: ../../Zotlabs/Module/Network.php:243 +#: ../../Zotlabs/Module/Network.php:242 msgid "Privacy group is empty" msgstr "Группа конфиденциальности пуста" -#: ../../Zotlabs/Module/Network.php:253 +#: ../../Zotlabs/Module/Network.php:252 msgid "Privacy group: " msgstr "Группа конфиденциальности: " -#: ../../Zotlabs/Module/Network.php:326 +#: ../../Zotlabs/Module/Network.php:325 #: ../../extend/addon/hzaddons/redred/Mod_Redred.php:29 msgid "Invalid channel." msgstr "Недействительный канал." @@ -5825,7 +6128,7 @@ msgstr "Введите название каталога" msgid "or select an existing folder (doubleclick)" msgstr "или выберите существующий каталог (двойной щелчок)" -#: ../../Zotlabs/Module/Filer.php:55 ../../Zotlabs/Lib/ThreadItem.php:185 +#: ../../Zotlabs/Module/Filer.php:55 ../../Zotlabs/Lib/ThreadItem.php:208 msgid "Save to Folder" msgstr "Сохранить в каталог" @@ -5849,94 +6152,94 @@ msgstr "Создать пользовательское приложение" msgid "Connection added." msgstr "Контакт добавлен." -#: ../../Zotlabs/Module/Like.php:106 +#: ../../Zotlabs/Module/Like.php:112 msgid "Like/Dislike" msgstr "Нравится / не нравится" -#: ../../Zotlabs/Module/Like.php:112 +#: ../../Zotlabs/Module/Like.php:118 msgid "This action is restricted to members." msgstr "Это действие доступно только участникам." -#: ../../Zotlabs/Module/Like.php:113 +#: ../../Zotlabs/Module/Like.php:119 msgid "" "Please login with your $Projectname ID or register as a new $Projectname member to continue." msgstr "Пожалуйста, для продолжения войдите с вашим $Projectname ID или зарегистрируйтесь как новый участник $Projectname." -#: ../../Zotlabs/Module/Like.php:166 ../../Zotlabs/Module/Like.php:192 -#: ../../Zotlabs/Module/Like.php:230 +#: ../../Zotlabs/Module/Like.php:172 ../../Zotlabs/Module/Like.php:198 +#: ../../Zotlabs/Module/Like.php:236 msgid "Invalid request." msgstr "Неверный запрос." -#: ../../Zotlabs/Module/Like.php:178 ../../include/conversation.php:135 +#: ../../Zotlabs/Module/Like.php:184 ../../include/conversation.php:135 msgid "channel" msgstr "канал" -#: ../../Zotlabs/Module/Like.php:207 +#: ../../Zotlabs/Module/Like.php:213 msgid "thing" msgstr "предмет" -#: ../../Zotlabs/Module/Like.php:253 +#: ../../Zotlabs/Module/Like.php:259 msgid "Channel unavailable." msgstr "Канал недоступен." -#: ../../Zotlabs/Module/Like.php:289 +#: ../../Zotlabs/Module/Like.php:295 msgid "Previous action reversed." msgstr "Предыдущее действие отменено." -#: ../../Zotlabs/Module/Like.php:471 ../../Zotlabs/Lib/Activity.php:3339 +#: ../../Zotlabs/Module/Like.php:477 ../../Zotlabs/Lib/Activity.php:3422 #: ../../include/conversation.php:174 -#: ../../extend/addon/hzaddons/pubcrawl/as.php:1977 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1978 #: ../../extend/addon/hzaddons/diaspora/Receiver.php:1572 #, php-format msgid "%1$s likes %2$s's %3$s" msgstr "%1$s нравится %3$s %2$s" -#: ../../Zotlabs/Module/Like.php:473 ../../Zotlabs/Lib/Activity.php:3341 +#: ../../Zotlabs/Module/Like.php:479 ../../Zotlabs/Lib/Activity.php:3424 #: ../../include/conversation.php:177 -#: ../../extend/addon/hzaddons/pubcrawl/as.php:1979 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1980 #, php-format msgid "%1$s doesn't like %2$s's %3$s" msgstr "%1$s не нравится %2$s %3$s" -#: ../../Zotlabs/Module/Like.php:475 +#: ../../Zotlabs/Module/Like.php:481 #, php-format msgid "%1$s agrees with %2$s's %3$s" msgstr "%1$s согласен с %2$s %3$s" -#: ../../Zotlabs/Module/Like.php:477 +#: ../../Zotlabs/Module/Like.php:483 #, php-format msgid "%1$s doesn't agree with %2$s's %3$s" msgstr "%1$s не согласен с %2$s %3$s" -#: ../../Zotlabs/Module/Like.php:479 +#: ../../Zotlabs/Module/Like.php:485 #, php-format msgid "%1$s abstains from a decision on %2$s's %3$s" msgstr "%1$s воздерживается от решения по %2$s%3$s" -#: ../../Zotlabs/Module/Like.php:481 +#: ../../Zotlabs/Module/Like.php:487 #: ../../extend/addon/hzaddons/diaspora/Receiver.php:2205 #, php-format msgid "%1$s is attending %2$s's %3$s" msgstr "%1$s посещает %2$s%3$s" -#: ../../Zotlabs/Module/Like.php:483 +#: ../../Zotlabs/Module/Like.php:489 #: ../../extend/addon/hzaddons/diaspora/Receiver.php:2207 #, php-format msgid "%1$s is not attending %2$s's %3$s" msgstr "%1$s не посещает %2$s%3$s" -#: ../../Zotlabs/Module/Like.php:485 +#: ../../Zotlabs/Module/Like.php:491 #: ../../extend/addon/hzaddons/diaspora/Receiver.php:2209 #, php-format msgid "%1$s may attend %2$s's %3$s" msgstr "%1$s может посетить %2$s%3$s" -#: ../../Zotlabs/Module/Like.php:586 +#: ../../Zotlabs/Module/Like.php:592 msgid "Action completed." msgstr "Действие завершено." -#: ../../Zotlabs/Module/Like.php:587 +#: ../../Zotlabs/Module/Like.php:593 msgid "Thank you." msgstr "Спасибо." @@ -5983,16 +6286,6 @@ msgstr "Разрешённые символы a-z 0-9, - и _" msgid "Channel name" msgstr "Название канала" -#: ../../Zotlabs/Module/New_channel.php:178 -msgid "" -"Select a channel permission role compatible with your usage needs and " -"privacy requirements." -msgstr "Выберите разрешения для канала в соответствии с вашими потребностями и требованиями безопасности." - -#: ../../Zotlabs/Module/New_channel.php:178 -msgid "Read more about channel permission roles" -msgstr "Прочитать больше о разрешениях для каналов" - #: ../../Zotlabs/Module/New_channel.php:181 msgid "Create a Channel" msgstr "Создать канал" @@ -6018,7 +6311,7 @@ msgid "Add Card" msgstr "Добавить карточку" #: ../../Zotlabs/Module/Cards.php:205 ../../Zotlabs/Lib/Apps.php:332 -#: ../../include/nav.php:506 +#: ../../include/nav.php:504 msgid "Cards" msgstr "Карточки" @@ -6058,7 +6351,7 @@ msgstr "Меню может использоваться, чтобы сохра msgid "Submit and proceed" msgstr "Отправить и обработать" -#: ../../Zotlabs/Module/Menu.php:171 ../../include/text.php:2689 +#: ../../Zotlabs/Module/Menu.php:171 ../../include/text.php:2717 msgid "Menus" msgstr "Меню" @@ -6119,12 +6412,12 @@ msgstr "Разрешить закладки" msgid "Public Stream" msgstr "Публичный поток" -#: ../../Zotlabs/Module/Search.php:249 +#: ../../Zotlabs/Module/Search.php:239 #, php-format msgid "Items tagged with: %s" msgstr "Объекты помечены как: %s" -#: ../../Zotlabs/Module/Search.php:251 +#: ../../Zotlabs/Module/Search.php:241 #, php-format msgid "Search results for: %s" msgstr "Результаты поиска для: %s" @@ -6302,7 +6595,7 @@ msgid "Export selected" msgstr "Экспортировать выбранное" #: ../../Zotlabs/Module/Webpages.php:249 ../../Zotlabs/Lib/Apps.php:347 -#: ../../include/nav.php:529 +#: ../../include/nav.php:527 msgid "Webpages" msgstr "Веб-страницы" @@ -6350,11 +6643,11 @@ msgstr "Комментарий удалён" msgid "Authentication failed." msgstr "Ошибка аутентификации." -#: ../../Zotlabs/Module/Rmagic.php:97 ../../include/channel.php:2562 +#: ../../Zotlabs/Module/Rmagic.php:97 ../../include/channel.php:2611 msgid "Enter your channel address (e.g. channel@example.com)" msgstr "Введите адрес вашего канала (например: channel@example.com)" -#: ../../Zotlabs/Module/Rmagic.php:98 ../../include/channel.php:2563 +#: ../../Zotlabs/Module/Rmagic.php:98 ../../include/channel.php:2612 msgid "Authenticate" msgstr "Проверка подлинности" @@ -6362,51 +6655,65 @@ msgstr "Проверка подлинности" msgid "Permissions denied." msgstr "Доступ запрещен." -#: ../../Zotlabs/Module/Import.php:165 +#: ../../Zotlabs/Module/Import.php:70 +msgid "Nothing to import." +msgstr "Ничего импортировать." + +#: ../../Zotlabs/Module/Import.php:86 ../../Zotlabs/Module/Import.php:100 +msgid "Unable to download data from old server" +msgstr "Невозможно загрузить данные со старого сервера" + +#: ../../Zotlabs/Module/Import.php:163 #, php-format msgid "Your service plan only allows %d channels." msgstr "Ваш класс обслуживания разрешает только %d каналов." -#: ../../Zotlabs/Module/Import.php:191 +#: ../../Zotlabs/Module/Import.php:190 msgid "No channel. Import failed." msgstr "Канала нет. Импорт невозможен." -#: ../../Zotlabs/Module/Import.php:576 +#: ../../Zotlabs/Module/Import.php:557 +msgid "" +"Automatic content and files import was not possible due to API version " +"incompatiblity. Please import content and files manually!" +msgstr "Автоматический импорт содержимого и файлов был невозможен из-за несовместимости версий API. Пожалуйста, импортируйте контент и файлы вручную!" + +#: ../../Zotlabs/Module/Import.php:585 msgid "You must be logged in to use this feature." msgstr "Вы должны войти в систему, чтобы использовать эту функцию." -#: ../../Zotlabs/Module/Import.php:583 +#: ../../Zotlabs/Module/Import.php:592 msgid "Channel Import" msgstr "Импортировать канал" -#: ../../Zotlabs/Module/Import.php:584 +#: ../../Zotlabs/Module/Import.php:593 msgid "" "Use this form to import an existing channel from a different server/hub. You " "may retrieve the channel identity from the old server/hub via the network or " "provide an export file." msgstr "Используйте эту форм для импорта существующего канала с другого сервера / хаба. Вы можете получить идентификационные данные канала со старого сервера / хаба через сеть или предоставить файл экспорта." -#: ../../Zotlabs/Module/Import.php:586 +#: ../../Zotlabs/Module/Import.php:595 msgid "Or provide the old server/hub details" msgstr "или предоставьте данные старого сервера" -#: ../../Zotlabs/Module/Import.php:588 +#: ../../Zotlabs/Module/Import.php:597 msgid "Your old identity address (xyz@example.com)" msgstr "Ваш старый адрес канала (xyz@example.com)" -#: ../../Zotlabs/Module/Import.php:589 +#: ../../Zotlabs/Module/Import.php:598 msgid "Your old login email address" msgstr "Ваш старый адрес электронной почты" -#: ../../Zotlabs/Module/Import.php:590 +#: ../../Zotlabs/Module/Import.php:599 msgid "Your old login password" msgstr "Ваш старый пароль" -#: ../../Zotlabs/Module/Import.php:591 +#: ../../Zotlabs/Module/Import.php:600 msgid "Import your items and files (limited by available memory)" msgstr "Импортировать ваши запиши и файлы (ограничено объёмом доступной памяти)" -#: ../../Zotlabs/Module/Import.php:593 +#: ../../Zotlabs/Module/Import.php:602 msgid "" "For either option, please choose whether to make this hub your new primary " "address, or whether your old location should continue this role. You will be " @@ -6414,96 +6721,104 @@ msgid "" "location for files, photos, and media." msgstr "Для любого варианта, пожалуйста, выберите, следует ли сделать этот хаб вашим новым основным адресом, или ваше прежнее местоположение должно продолжить выполнять эту роль. Вы сможете отправлять сообщения из любого местоположения, но только одно может быть помечено как основное место для файлов, фотографий и мультимедиа." -#: ../../Zotlabs/Module/Import.php:595 +#: ../../Zotlabs/Module/Import.php:604 msgid "Make this hub my primary location" msgstr "Сделать этот хаб главным" -#: ../../Zotlabs/Module/Import.php:596 +#: ../../Zotlabs/Module/Import.php:605 msgid "Move this channel (disable all previous locations)" msgstr "Переместить это канал (отключить все предыдущие месторасположения)" -#: ../../Zotlabs/Module/Import.php:597 +#: ../../Zotlabs/Module/Import.php:606 msgid "Use this channel nickname instead of the one provided" msgstr "Использовать псевдоним этого канала вместо предоставленного" -#: ../../Zotlabs/Module/Import.php:597 +#: ../../Zotlabs/Module/Import.php:606 msgid "" "Leave blank to keep your existing channel nickname. You will be randomly " "assigned a similar nickname if either name is already allocated on this site." msgstr "Оставьте пустым для сохранения существующего псевдонима канала. Вам будет случайным образом назначен похожий псевдоним если такое имя уже выделено на этом сайте." -#: ../../Zotlabs/Module/Import.php:599 +#: ../../Zotlabs/Module/Import.php:608 msgid "" "This process may take several minutes to complete. Please submit the form " "only once and leave this page open until finished." msgstr "Процесс может занять несколько минут. Пожалуйста, отправьте форму только один раз и оставьте эту страницу открытой до завершения." -#: ../../Zotlabs/Module/Group.php:46 +#: ../../Zotlabs/Module/Group.php:47 msgid "Privacy group created." msgstr "Группа конфиденциальности создана." -#: ../../Zotlabs/Module/Group.php:49 +#: ../../Zotlabs/Module/Group.php:50 msgid "Could not create privacy group." msgstr "Не удалось создать группу конфиденциальности." -#: ../../Zotlabs/Module/Group.php:62 ../../Zotlabs/Module/Group.php:212 -#: ../../include/items.php:4249 +#: ../../Zotlabs/Module/Group.php:62 ../../Zotlabs/Module/Group.php:232 +#: ../../include/items.php:4381 msgid "Privacy group not found." msgstr "Группа конфиденциальности не найдена." -#: ../../Zotlabs/Module/Group.php:81 +#: ../../Zotlabs/Module/Group.php:82 msgid "Privacy group updated." msgstr "Группа конфиденциальности обновлена." -#: ../../Zotlabs/Module/Group.php:140 ../../Zotlabs/Module/Group.php:152 -#: ../../Zotlabs/Lib/Group.php:324 ../../Zotlabs/Lib/Apps.php:370 +#: ../../Zotlabs/Module/Group.php:151 ../../Zotlabs/Module/Group.php:330 +msgid "Post to this group by default" +msgstr "Публиковать в этой группе по умолчанию" + +#: ../../Zotlabs/Module/Group.php:152 ../../Zotlabs/Module/Group.php:331 +msgid "Add new contacts to this group by default" +msgstr "Добавлять новые контакты в эту группу по умолчанию" + +#: ../../Zotlabs/Module/Group.php:157 ../../Zotlabs/Module/Group.php:171 +#: ../../Zotlabs/Lib/Apps.php:370 ../../Zotlabs/Lib/AccessList.php:349 #: ../../Zotlabs/Widget/Activity_filter.php:88 ../../include/group.php:327 -#: ../../include/nav.php:101 ../../include/acl_selectors.php:87 +#: ../../include/acl_selectors.php:87 msgid "Privacy Groups" msgstr "Группы конфиденциальности" -#: ../../Zotlabs/Module/Group.php:141 +#: ../../Zotlabs/Module/Group.php:158 msgid "Add Group" msgstr "Добавить группу" -#: ../../Zotlabs/Module/Group.php:145 +#: ../../Zotlabs/Module/Group.php:162 msgid "Privacy group name" msgstr "Имя группы конфиденциальности" -#: ../../Zotlabs/Module/Group.php:146 ../../Zotlabs/Module/Group.php:255 +#: ../../Zotlabs/Module/Group.php:163 ../../Zotlabs/Module/Group.php:275 msgid "Members are visible to other channels" msgstr "Участники канала видимые для остальных" -#: ../../Zotlabs/Module/Group.php:181 +#: ../../Zotlabs/Module/Group.php:201 msgid "Privacy group removed." msgstr "Группа конфиденциальности удалена." -#: ../../Zotlabs/Module/Group.php:184 +#: ../../Zotlabs/Module/Group.php:204 msgid "Unable to remove privacy group." msgstr "Ну удалось удалить группу конфиденциальности." -#: ../../Zotlabs/Module/Group.php:250 +#: ../../Zotlabs/Module/Group.php:270 #, php-format msgid "Privacy Group: %s" msgstr "Группа конфиденциальности: %s" -#: ../../Zotlabs/Module/Group.php:252 +#: ../../Zotlabs/Module/Group.php:272 msgid "Privacy group name: " msgstr "Название группы конфиденциальности: " -#: ../../Zotlabs/Module/Group.php:257 +#: ../../Zotlabs/Module/Group.php:277 msgid "Delete Group" msgstr "Удалить группу" -#: ../../Zotlabs/Module/Group.php:268 +#: ../../Zotlabs/Module/Group.php:288 msgid "Group members" msgstr "Члены группы" -#: ../../Zotlabs/Module/Group.php:270 +#: ../../Zotlabs/Module/Group.php:290 msgid "Not in this group" msgstr "Не в этой группе" -#: ../../Zotlabs/Module/Group.php:302 +#: ../../Zotlabs/Module/Group.php:322 msgid "Click a channel to toggle membership" msgstr "Нажмите на канал для просмотра членства" @@ -6511,279 +6826,123 @@ msgstr "Нажмите на канал для просмотра членств msgid "vcard" msgstr "vCard" -#: ../../Zotlabs/Module/Connedit.php:121 -msgid "Could not locate selected profile." -msgstr "Не удалось обнаружить выбранный профиль." - -#: ../../Zotlabs/Module/Connedit.php:262 +#: ../../Zotlabs/Module/Connedit.php:171 msgid "Connection updated." msgstr "Контакты обновлены." -#: ../../Zotlabs/Module/Connedit.php:264 +#: ../../Zotlabs/Module/Connedit.php:173 msgid "Failed to update connection record." msgstr "Не удалось обновить запись контакта." -#: ../../Zotlabs/Module/Connedit.php:307 -msgid "is now connected to" -msgstr "теперь подключён к" - -#: ../../Zotlabs/Module/Connedit.php:432 +#: ../../Zotlabs/Module/Connedit.php:320 msgid "Could not access address book record." msgstr "Не удалось получить доступ к записи адресной книги." -#: ../../Zotlabs/Module/Connedit.php:480 +#: ../../Zotlabs/Module/Connedit.php:368 msgid "Refresh failed - channel is currently unavailable." msgstr "Обновление невозможно - в настоящее время канал недоступен." -#: ../../Zotlabs/Module/Connedit.php:494 ../../Zotlabs/Module/Connedit.php:503 -#: ../../Zotlabs/Module/Connedit.php:512 ../../Zotlabs/Module/Connedit.php:521 -#: ../../Zotlabs/Module/Connedit.php:534 +#: ../../Zotlabs/Module/Connedit.php:382 ../../Zotlabs/Module/Connedit.php:391 +#: ../../Zotlabs/Module/Connedit.php:400 ../../Zotlabs/Module/Connedit.php:409 +#: ../../Zotlabs/Module/Connedit.php:422 msgid "Unable to set address book parameters." msgstr "Не удалось получить доступ к параметрам адресной книги." -#: ../../Zotlabs/Module/Connedit.php:553 +#: ../../Zotlabs/Module/Connedit.php:441 msgid "Connection has been removed." msgstr "Контакт был удалён." -#: ../../Zotlabs/Module/Connedit.php:593 ../../Zotlabs/Lib/Apps.php:350 -#: ../../include/nav.php:112 ../../include/conversation.php:1086 -#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:58 -msgid "View Profile" -msgstr "Просмотреть профиль" - -#: ../../Zotlabs/Module/Connedit.php:596 -#, php-format -msgid "View %s's profile" -msgstr "Просмотр %s профиля" - -#: ../../Zotlabs/Module/Connedit.php:600 -msgid "Refresh Permissions" -msgstr "Обновить разрешения" - -#: ../../Zotlabs/Module/Connedit.php:603 -msgid "Fetch updated permissions" -msgstr "Получить обновлённые разрешения" - -#: ../../Zotlabs/Module/Connedit.php:607 -msgid "Refresh Photo" -msgstr "Обновить фотографию" - -#: ../../Zotlabs/Module/Connedit.php:610 -msgid "Fetch updated photo" -msgstr "Получить обновлённую фотографию" - -#: ../../Zotlabs/Module/Connedit.php:614 ../../include/conversation.php:1096 -msgid "Recent Activity" -msgstr "Последние действия" - -#: ../../Zotlabs/Module/Connedit.php:617 -msgid "View recent posts and comments" -msgstr "Просмотреть последние публикации и комментарии" - -#: ../../Zotlabs/Module/Connedit.php:624 -msgid "Block (or Unblock) all communications with this connection" -msgstr "Блокировать (или разблокировать) связи с этим контактом" - -#: ../../Zotlabs/Module/Connedit.php:625 -msgid "This connection is blocked!" -msgstr "Этот контакт заблокирован!" - -#: ../../Zotlabs/Module/Connedit.php:629 -msgid "Unignore" -msgstr "Не игнорировать" - -#: ../../Zotlabs/Module/Connedit.php:632 -msgid "Ignore (or Unignore) all inbound communications from this connection" -msgstr "Игнорировать (или не игнорировать) все связи для этого контакта" - -#: ../../Zotlabs/Module/Connedit.php:633 -msgid "This connection is ignored!" -msgstr "Этот контакт игнорируется!" - -#: ../../Zotlabs/Module/Connedit.php:637 -msgid "Unarchive" -msgstr "Разархивировать" - -#: ../../Zotlabs/Module/Connedit.php:637 -msgid "Archive" -msgstr "Заархивировать" - -#: ../../Zotlabs/Module/Connedit.php:640 -msgid "" -"Archive (or Unarchive) this connection - mark channel dead but keep content" -msgstr "Заархивировать (или разархивировать) этот контакт - пометить канал отключённым но сохранить содержимое" - -#: ../../Zotlabs/Module/Connedit.php:641 -msgid "This connection is archived!" -msgstr "Этот контакт заархивирован!" - -#: ../../Zotlabs/Module/Connedit.php:645 -msgid "Unhide" -msgstr "Показать" - -#: ../../Zotlabs/Module/Connedit.php:645 -msgid "Hide" -msgstr "Скрыть" - -#: ../../Zotlabs/Module/Connedit.php:648 -msgid "Hide or Unhide this connection from your other connections" -msgstr "Скрыть или показать этот контакт от / для остальных" +#: ../../Zotlabs/Module/Connedit.php:480 ../../Zotlabs/Lib/Apps.php:350 +#: ../../include/nav.php:110 ../../include/conversation.php:1086 +#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:58 +msgid "View Profile" +msgstr "Просмотреть профиль" -#: ../../Zotlabs/Module/Connedit.php:649 -msgid "This connection is hidden!" -msgstr "Этот контакт скрыт!" +#: ../../Zotlabs/Module/Connedit.php:483 +#, php-format +msgid "View %s's profile" +msgstr "Просмотр %s профиля" -#: ../../Zotlabs/Module/Connedit.php:656 -msgid "Delete this connection" -msgstr "Удалить этот контакт" +#: ../../Zotlabs/Module/Connedit.php:501 ../../include/conversation.php:1098 +msgid "Recent Activity" +msgstr "Последние действия" + +#: ../../Zotlabs/Module/Connedit.php:504 +msgid "View recent posts and comments" +msgstr "Просмотреть последние публикации и комментарии" -#: ../../Zotlabs/Module/Connedit.php:664 +#: ../../Zotlabs/Module/Connedit.php:550 msgid "Fetch Vcard" msgstr "Получить vCard" -#: ../../Zotlabs/Module/Connedit.php:667 +#: ../../Zotlabs/Module/Connedit.php:553 msgid "Fetch electronic calling card for this connection" msgstr "Получить электронную телефонную карточку для этого контакта" -#: ../../Zotlabs/Module/Connedit.php:678 -msgid "Open Individual Permissions section by default" -msgstr "Открывать раздел \"Индивидуальные разрешения\" по умолчанию" - -#: ../../Zotlabs/Module/Connedit.php:701 +#: ../../Zotlabs/Module/Connedit.php:572 msgid "Affinity" msgstr "Сходство" -#: ../../Zotlabs/Module/Connedit.php:704 +#: ../../Zotlabs/Module/Connedit.php:575 msgid "Open Set Affinity section by default" msgstr "Открыть секцию установления сходства по умолчанию" -#: ../../Zotlabs/Module/Connedit.php:708 ../../Zotlabs/Widget/Affinity.php:30 -msgid "Me" -msgstr "Я" - -#: ../../Zotlabs/Module/Connedit.php:709 ../../Zotlabs/Widget/Affinity.php:31 -msgid "Family" -msgstr "Семья" - -#: ../../Zotlabs/Module/Connedit.php:711 ../../Zotlabs/Widget/Affinity.php:33 -msgid "Acquaintances" -msgstr "Знакомые" - -#: ../../Zotlabs/Module/Connedit.php:741 +#: ../../Zotlabs/Module/Connedit.php:612 msgid "Filter" msgstr "Фильтр" -#: ../../Zotlabs/Module/Connedit.php:744 +#: ../../Zotlabs/Module/Connedit.php:615 msgid "Open Custom Filter section by default" msgstr "Открывать секцию \"Настраиваемый фильтр\" по умолчанию" -#: ../../Zotlabs/Module/Connedit.php:781 -msgid "Approve this connection" -msgstr "Утвердить этот контакт" - -#: ../../Zotlabs/Module/Connedit.php:781 -msgid "Accept connection to allow communication" -msgstr "Принять контакт чтобы разрешить связь" - -#: ../../Zotlabs/Module/Connedit.php:786 +#: ../../Zotlabs/Module/Connedit.php:626 msgid "Set Affinity" msgstr "Установить сходство" -#: ../../Zotlabs/Module/Connedit.php:789 +#: ../../Zotlabs/Module/Connedit.php:629 msgid "Set Profile" msgstr "Установить профиль" -#: ../../Zotlabs/Module/Connedit.php:792 +#: ../../Zotlabs/Module/Connedit.php:632 msgid "Set Affinity & Profile" msgstr "Установить сходство и профиль" -#: ../../Zotlabs/Module/Connedit.php:840 -msgid "This connection is unreachable from this location." -msgstr "Этот контакт недоступен для данного местоположения" - -#: ../../Zotlabs/Module/Connedit.php:841 -msgid "This connection may be unreachable from other channel locations." -msgstr "Этот контакт может быть недоступен из других мест размещения канала" - -#: ../../Zotlabs/Module/Connedit.php:843 -msgid "Location independence is not supported by their network." -msgstr "Независимое местоположение не поддерживается их сетью." - -#: ../../Zotlabs/Module/Connedit.php:849 -msgid "" -"This connection is unreachable from this location. Location independence is " -"not supported by their network." -msgstr "Этот контакт недоступен из данного местоположения. Независимое местоположение не поддерживается их сетью." - -#: ../../Zotlabs/Module/Connedit.php:852 ../../include/items.php:4282 +#: ../../Zotlabs/Module/Connedit.php:685 #, php-format -msgid "Connection: %s" +msgid "Contact: %s" msgstr "Контакт: %s" -#: ../../Zotlabs/Module/Connedit.php:853 -msgid "Connection requests will be approved without your interaction" -msgstr "Запросы контактов будут одобрены без вашего участия" +#: ../../Zotlabs/Module/Connedit.php:687 +msgid "Manage contact roles" +msgstr "Управление ролями контактов" -#: ../../Zotlabs/Module/Connedit.php:862 -msgid "This connection's primary address is" -msgstr "Главный адрес это контакта" +#: ../../Zotlabs/Module/Connedit.php:694 +msgid "This contacts's primary address is" +msgstr "Основной адрес этого контакта:" -#: ../../Zotlabs/Module/Connedit.php:863 +#: ../../Zotlabs/Module/Connedit.php:695 msgid "Available locations:" msgstr "Доступные расположения:" -#: ../../Zotlabs/Module/Connedit.php:869 -msgid "Connection Tools" -msgstr "Инструменты контактов" - -#: ../../Zotlabs/Module/Connedit.php:871 -msgid "Slide to adjust your degree of friendship" -msgstr "Прокрутить для настройки степени дружбы" - -#: ../../Zotlabs/Module/Connedit.php:872 ../../include/js_strings.php:20 -msgid "Rating" -msgstr "Оценка" - -#: ../../Zotlabs/Module/Connedit.php:873 -msgid "Slide to adjust your rating" -msgstr "Прокрутить для настройки оценки" - -#: ../../Zotlabs/Module/Connedit.php:874 ../../Zotlabs/Module/Connedit.php:879 -msgid "Optionally explain your rating" -msgstr "Объясните свою оценку (не обязательно)" - -#: ../../Zotlabs/Module/Connedit.php:876 -msgid "Custom Filter" -msgstr "Настраиваемый фильтр" - -#: ../../Zotlabs/Module/Connedit.php:877 -msgid "Only import posts with this text" -msgstr "Импортировать публикации только с этим текстом" - -#: ../../Zotlabs/Module/Connedit.php:878 -msgid "Do not import posts with this text" -msgstr "Не импортировать публикации с этим текстом" - -#: ../../Zotlabs/Module/Connedit.php:880 -msgid "This information is public!" -msgstr "Эта информация общедоступна!" - -#: ../../Zotlabs/Module/Connedit.php:885 -msgid "Connection Pending Approval" -msgstr "Ожидающие подтверждения контактов" +#: ../../Zotlabs/Module/Connedit.php:710 +msgid "Contact Pending Approval" +msgstr "Контакты ожидающие утверждения" -#: ../../Zotlabs/Module/Connedit.php:890 +#: ../../Zotlabs/Module/Connedit.php:715 #, php-format msgid "" "Please choose the profile you would like to display to %s when viewing your " "profile securely." msgstr "Пожалуйста, выберите профиль который вы хотит показывать в %s при безопасном просмотре." -#: ../../Zotlabs/Module/Connedit.php:892 ../../Zotlabs/Module/Tokens.php:178 -msgid "Their Settings" -msgstr "Их настройки" +#: ../../Zotlabs/Module/Connedit.php:721 +msgid "" +"Some permissions may be inherited from your channel's privacy settings, which have higher priority than " +"individual settings. You can not change those settings here." +msgstr "Некоторые разрешения могут наследовать из настроек приватности ваших каналов которые могут иметь более высокий приоритет чем индивидуальные. Вы не можете менять эти настройки здесь." -#: ../../Zotlabs/Module/Connedit.php:897 +#: ../../Zotlabs/Module/Connedit.php:722 msgid "" "Some permissions may be inherited from your channel's privacy settings, which have higher priority than " @@ -6791,11 +6950,11 @@ msgid "" "any impact unless the inherited setting changes." msgstr "Некоторые разрешения могут быть унаследованы из настроек приватности вашего канала, которые могут иметь более высокий приоритет чем индивидуальные. Вы можете изменить эти настройки, однако они не будут применены до изменения переданных по наследству настроек." -#: ../../Zotlabs/Module/Connedit.php:898 +#: ../../Zotlabs/Module/Connedit.php:723 msgid "Last update:" msgstr "Последнее обновление:" -#: ../../Zotlabs/Module/Connedit.php:906 +#: ../../Zotlabs/Module/Connedit.php:731 msgid "Details" msgstr "Сведения" @@ -6881,7 +7040,7 @@ msgid "Add Article" msgstr "Добавить статью" #: ../../Zotlabs/Module/Articles.php:223 ../../Zotlabs/Lib/Apps.php:331 -#: ../../include/nav.php:517 +#: ../../include/nav.php:515 msgid "Articles" msgstr "Статьи" @@ -7374,6 +7533,10 @@ msgstr "Невозможно добавить элемент меню." msgid "Menu Item Permissions" msgstr "Разрешения на пункт меню" +#: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247 +msgid "(click to open/close)" +msgstr "(нажмите чтобы открыть/закрыть)" + #: ../../Zotlabs/Module/Mitem.php:174 ../../Zotlabs/Module/Mitem.php:191 msgid "Link Name" msgstr "Имя ссылки" @@ -7503,7 +7666,7 @@ msgstr "Статистика" msgid "Software" msgstr "Программное обеспечение" -#: ../../Zotlabs/Module/Pubsites.php:35 ../../include/conversation.php:1136 +#: ../../Zotlabs/Module/Pubsites.php:35 ../../include/conversation.php:1146 msgid "Ratings" msgstr "Оценки" @@ -7645,7 +7808,7 @@ msgid "NEW" msgstr "НОВОЕ" #: ../../Zotlabs/Module/Sharedwithme.php:108 -#: ../../Zotlabs/Storage/Browser.php:379 ../../include/text.php:1541 +#: ../../Zotlabs/Storage/Browser.php:379 ../../include/text.php:1538 msgid "Size" msgstr "Размер" @@ -7726,12 +7889,12 @@ msgstr "Статус:" msgid "Homepage: " msgstr "Домашняя страница:" -#: ../../Zotlabs/Module/Directory.php:348 ../../include/channel.php:1764 +#: ../../Zotlabs/Module/Directory.php:348 ../../include/channel.php:1799 msgid "Age:" msgstr "Возраст:" #: ../../Zotlabs/Module/Directory.php:353 ../../include/event.php:63 -#: ../../include/event.php:134 ../../include/channel.php:1591 +#: ../../include/event.php:134 ../../include/channel.php:1625 msgid "Location:" msgstr "Местоположение:" @@ -7739,11 +7902,12 @@ msgstr "Местоположение:" msgid "Description:" msgstr "Описание:" -#: ../../Zotlabs/Module/Directory.php:366 ../../include/channel.php:1793 +#: ../../Zotlabs/Module/Directory.php:366 ../../include/channel.php:1632 +#: ../../include/channel.php:1828 msgid "Hometown:" msgstr "Родной город:" -#: ../../Zotlabs/Module/Directory.php:368 ../../include/channel.php:1799 +#: ../../Zotlabs/Module/Directory.php:368 ../../include/channel.php:1834 msgid "About:" msgstr "О себе:" @@ -7856,7 +8020,7 @@ msgid "Error downloading wiki: " msgstr "Ошибка загрузки Wiki:" #: ../../Zotlabs/Module/Wiki.php:203 ../../Zotlabs/Widget/Wiki_list.php:15 -#: ../../include/nav.php:541 +#: ../../include/nav.php:539 msgid "Wikis" msgstr "" @@ -7875,19 +8039,19 @@ msgstr "Тип содержимого" #: ../../Zotlabs/Module/Wiki.php:214 ../../Zotlabs/Module/Wiki.php:368 #: ../../Zotlabs/Widget/Wiki_pages.php:38 -#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2115 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2143 #: ../../extend/addon/hzaddons/mdpost/mdpost.php:41 msgid "Markdown" msgstr "Разметка Markdown" #: ../../Zotlabs/Module/Wiki.php:214 ../../Zotlabs/Module/Wiki.php:368 #: ../../Zotlabs/Widget/Wiki_pages.php:38 -#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2113 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2141 msgid "BBcode" msgstr "" #: ../../Zotlabs/Module/Wiki.php:214 ../../Zotlabs/Widget/Wiki_pages.php:38 -#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2116 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:2144 msgid "Text" msgstr "Текст" @@ -7931,7 +8095,7 @@ msgstr "Новая страница" msgid "Revision Comparison" msgstr "Сравнение ревизий" -#: ../../Zotlabs/Module/Wiki.php:364 ../../Zotlabs/Lib/NativeWikiPage.php:579 +#: ../../Zotlabs/Module/Wiki.php:364 ../../Zotlabs/Lib/NativeWikiPage.php:585 #: ../../Zotlabs/Widget/Wiki_page_history.php:25 msgid "Revert" msgstr "Отменить" @@ -7957,7 +8121,7 @@ msgstr "Новое имя страницы" msgid "Embed image from photo albums" msgstr "Встроить изображение из фотоальбома" -#: ../../Zotlabs/Module/Wiki.php:397 ../../include/conversation.php:1463 +#: ../../Zotlabs/Module/Wiki.php:397 ../../include/conversation.php:1477 #: ../../extend/addon/hzaddons/hsse/hsse.php:208 msgid "Embed an image from your albums" msgstr "Встроить изображение из ваших альбомов" @@ -8019,56 +8183,60 @@ msgid "You must be authenticated." msgstr "Вы должны быть аутентифицированы." #: ../../Zotlabs/Module/Fbrowser.php:29 ../../Zotlabs/Lib/Apps.php:351 -#: ../../include/nav.php:449 ../../include/features.php:368 +#: ../../include/nav.php:447 ../../include/features.php:368 msgid "Photos" msgstr "Фотографии" #: ../../Zotlabs/Module/Fbrowser.php:85 ../../Zotlabs/Storage/Browser.php:351 #: ../../Zotlabs/Lib/Apps.php:346 ../../Zotlabs/Widget/Notifications.php:101 -#: ../../include/nav.php:457 +#: ../../include/nav.php:455 msgid "Files" msgstr "Файлы" -#: ../../Zotlabs/Module/Tokens.php:39 +#: ../../Zotlabs/Module/Tokens.php:49 #, php-format msgid "This channel is limited to %d tokens" msgstr "Этот канал ограничен %d токенами" -#: ../../Zotlabs/Module/Tokens.php:45 +#: ../../Zotlabs/Module/Tokens.php:55 msgid "Name and Password are required." msgstr "Требуются имя и пароль." -#: ../../Zotlabs/Module/Tokens.php:85 +#: ../../Zotlabs/Module/Tokens.php:170 msgid "Token saved." msgstr "Токен сохранён." -#: ../../Zotlabs/Module/Tokens.php:131 +#: ../../Zotlabs/Module/Tokens.php:251 msgid "" "Use this form to create temporary access identifiers to share things with " "non-members. These identities may be used in Access Control Lists and " "visitors may login using these credentials to access private content." msgstr "Используйте эту форму для создания идентификаторов временного доступа для сторонних пользователей. Эти идентификаторы могут использоваться в списках контроля доступа, и посетители могут использовать эти учетные данные для доступа к частному контенту." -#: ../../Zotlabs/Module/Tokens.php:133 +#: ../../Zotlabs/Module/Tokens.php:253 msgid "" "You may also provide dropbox style access links to friends and " "associates by adding the Login Password to any specific site URL as shown. " "Examples:" msgstr "Вы также можете предоставить доступ в стиле dropbox для друзей и коллег, добавив имя и пароль для входа на любой URL-адрес сайта. Например:" -#: ../../Zotlabs/Module/Tokens.php:168 +#: ../../Zotlabs/Module/Tokens.php:282 +msgid "Select a role for this token" +msgstr "Выбрать роль для этого токена" + +#: ../../Zotlabs/Module/Tokens.php:283 msgid "Guest Access Tokens" msgstr "Токен гостевого доступа" -#: ../../Zotlabs/Module/Tokens.php:175 +#: ../../Zotlabs/Module/Tokens.php:290 msgid "Login Name" msgstr "Имя" -#: ../../Zotlabs/Module/Tokens.php:176 +#: ../../Zotlabs/Module/Tokens.php:291 msgid "Login Password" msgstr "Пароль" -#: ../../Zotlabs/Module/Tokens.php:177 +#: ../../Zotlabs/Module/Tokens.php:292 msgid "Expires (yyyy-mm-dd)" msgstr "Срок действия (yyyy-mm-dd)" @@ -8122,7 +8290,7 @@ msgstr "Общие" msgid "Add Files" msgstr "Добавить файлы" -#: ../../Zotlabs/Storage/Browser.php:369 ../../Zotlabs/Lib/ThreadItem.php:175 +#: ../../Zotlabs/Storage/Browser.php:369 ../../Zotlabs/Lib/ThreadItem.php:198 msgid "Admin Delete" msgstr "Удалено администратором" @@ -8202,39 +8370,6 @@ msgid "" "an existing folder." msgstr "Вы можете выбрать файлы с помощью кнопки загрузки или перетащить их сюда или в существующую папку." -#: ../../Zotlabs/Lib/Group.php:28 ../../include/group.php:23 -msgid "" -"A deleted group with this name was revived. Existing item permissions " -"may apply to this group and any future members. If this is " -"not what you intended, please create another group with a different name." -msgstr "Удаленная группа с этим названием была восстановлена. Существующие разрешения пункт могут применяться к этой группе и к её будущих участников. Если это не то, чего вы хотели, пожалуйста, создайте другую группу с другим именем." - -#: ../../Zotlabs/Lib/Group.php:270 ../../include/group.php:271 -msgid "Add new connections to this privacy group" -msgstr "Добавить новые контакты в группу конфиденциальности" - -#: ../../Zotlabs/Lib/Group.php:302 ../../Zotlabs/Lib/AccessList.php:311 -#: ../../include/group.php:305 -msgid "edit" -msgstr "редактировать" - -#: ../../Zotlabs/Lib/Group.php:325 ../../include/group.php:328 -msgid "Edit group" -msgstr "Редактировать группу" - -#: ../../Zotlabs/Lib/Group.php:326 ../../include/group.php:329 -msgid "Add privacy group" -msgstr "Добавить группу конфиденциальности" - -#: ../../Zotlabs/Lib/Group.php:327 ../../include/group.php:330 -msgid "Channels not in any privacy group" -msgstr "Каналы не включены ни в одну группу конфиденциальности" - -#: ../../Zotlabs/Lib/Group.php:329 ../../Zotlabs/Lib/AccessList.php:336 -#: ../../Zotlabs/Widget/Savedsearch.php:84 ../../include/group.php:332 -msgid "add" -msgstr "добавить" - #: ../../Zotlabs/Lib/Connect.php:46 ../../Zotlabs/Lib/Connect.php:143 msgid "Channel is blocked on this site." msgstr "Канал блокируется на этом сайте." @@ -8259,7 +8394,7 @@ msgstr "Протокол отключен." msgid "Cannot connect to yourself." msgstr "Нельзя подключиться к самому себе." -#: ../../Zotlabs/Lib/Connect.php:271 +#: ../../Zotlabs/Lib/Connect.php:272 msgid "error saving data" msgstr "ошибка сохранения данных" @@ -8277,171 +8412,171 @@ msgstr "Ошибка обновления на %s" msgid "Update %s failed. See error logs." msgstr "Выполнение %s неудачно. Проверьте системный журнал." -#: ../../Zotlabs/Lib/NativeWikiPage.php:42 -#: ../../Zotlabs/Lib/NativeWikiPage.php:94 +#: ../../Zotlabs/Lib/NativeWikiPage.php:43 +#: ../../Zotlabs/Lib/NativeWikiPage.php:111 msgid "(No Title)" msgstr "(нет заголовка)" -#: ../../Zotlabs/Lib/NativeWikiPage.php:109 +#: ../../Zotlabs/Lib/NativeWikiPage.php:125 msgid "Wiki page create failed." msgstr "Не удалось создать страницу Wiki." -#: ../../Zotlabs/Lib/NativeWikiPage.php:123 +#: ../../Zotlabs/Lib/NativeWikiPage.php:139 msgid "Wiki not found." msgstr "Wiki не найдена." -#: ../../Zotlabs/Lib/NativeWikiPage.php:134 +#: ../../Zotlabs/Lib/NativeWikiPage.php:150 msgid "Destination name already exists" msgstr "Имя назначения уже существует" -#: ../../Zotlabs/Lib/NativeWikiPage.php:167 -#: ../../Zotlabs/Lib/NativeWikiPage.php:368 +#: ../../Zotlabs/Lib/NativeWikiPage.php:183 +#: ../../Zotlabs/Lib/NativeWikiPage.php:378 msgid "Page not found" msgstr "Страница не найдена." -#: ../../Zotlabs/Lib/NativeWikiPage.php:200 +#: ../../Zotlabs/Lib/NativeWikiPage.php:213 msgid "Error reading page content" msgstr "Ошибка чтения содержимого страницы" -#: ../../Zotlabs/Lib/NativeWikiPage.php:359 -#: ../../Zotlabs/Lib/NativeWikiPage.php:409 -#: ../../Zotlabs/Lib/NativeWikiPage.php:480 -#: ../../Zotlabs/Lib/NativeWikiPage.php:522 +#: ../../Zotlabs/Lib/NativeWikiPage.php:369 +#: ../../Zotlabs/Lib/NativeWikiPage.php:419 +#: ../../Zotlabs/Lib/NativeWikiPage.php:487 +#: ../../Zotlabs/Lib/NativeWikiPage.php:528 msgid "Error reading wiki" msgstr "Ошибка чтения Wiki" -#: ../../Zotlabs/Lib/NativeWikiPage.php:396 +#: ../../Zotlabs/Lib/NativeWikiPage.php:406 msgid "Page update failed." msgstr "Не удалось обновить страницу." -#: ../../Zotlabs/Lib/NativeWikiPage.php:431 +#: ../../Zotlabs/Lib/NativeWikiPage.php:441 msgid "Nothing deleted" msgstr "Ничего не удалено" -#: ../../Zotlabs/Lib/NativeWikiPage.php:501 +#: ../../Zotlabs/Lib/NativeWikiPage.php:508 msgid "Compare: object not found." msgstr "Сравнение: объект не найден." -#: ../../Zotlabs/Lib/NativeWikiPage.php:508 +#: ../../Zotlabs/Lib/NativeWikiPage.php:515 msgid "Page updated" msgstr "Страница обновлена" -#: ../../Zotlabs/Lib/NativeWikiPage.php:511 -msgid "Untitled" -msgstr "Не озаглавлено" - -#: ../../Zotlabs/Lib/NativeWikiPage.php:517 +#: ../../Zotlabs/Lib/NativeWikiPage.php:523 msgid "Wiki resource_id required for git commit" msgstr "Требуется resource_id Wiki для отправки в Git" -#: ../../Zotlabs/Lib/NativeWikiPage.php:577 +#: ../../Zotlabs/Lib/NativeWikiPage.php:583 #: ../../Zotlabs/Widget/Wiki_page_history.php:23 msgctxt "wiki_history" msgid "Message" msgstr "Сообщение" -#: ../../Zotlabs/Lib/NativeWikiPage.php:578 +#: ../../Zotlabs/Lib/NativeWikiPage.php:584 #: ../../Zotlabs/Widget/Wiki_page_history.php:24 msgid "Date" msgstr "Дата" -#: ../../Zotlabs/Lib/NativeWikiPage.php:580 +#: ../../Zotlabs/Lib/NativeWikiPage.php:586 #: ../../Zotlabs/Widget/Wiki_page_history.php:26 msgid "Compare" msgstr "Сравнить" -#: ../../Zotlabs/Lib/NativeWikiPage.php:618 ../../include/bbcode.php:1050 -#: ../../include/bbcode.php:1238 +#: ../../Zotlabs/Lib/NativeWikiPage.php:624 ../../include/bbcode.php:1050 +#: ../../include/bbcode.php:1235 msgid "Different viewers will see this text differently" msgstr "Различные зрители увидят этот текст по-разному" -#: ../../Zotlabs/Lib/ThreadItem.php:103 ../../include/conversation.php:742 -msgid "Private Message" -msgstr "Личное сообщение" +#: ../../Zotlabs/Lib/ThreadItem.php:109 +msgid "Restricted message" +msgstr "Сообщение с ограниченным доступом" -#: ../../Zotlabs/Lib/ThreadItem.php:131 +#: ../../Zotlabs/Lib/ThreadItem.php:116 +msgid "Public Policy" +msgstr "Политика общего доступа" + +#: ../../Zotlabs/Lib/ThreadItem.php:154 msgid "Privacy conflict. Discretion advised." msgstr "Конфиликт настроек конфиденциальности." -#: ../../Zotlabs/Lib/ThreadItem.php:181 ../../include/conversation.php:729 +#: ../../Zotlabs/Lib/ThreadItem.php:204 ../../include/conversation.php:729 msgid "Select" msgstr "Выбрать" -#: ../../Zotlabs/Lib/ThreadItem.php:206 ../../Zotlabs/Widget/Pinned.php:70 +#: ../../Zotlabs/Lib/ThreadItem.php:229 ../../Zotlabs/Widget/Pinned.php:70 msgid "I will attend" msgstr "Я буду участвовать" -#: ../../Zotlabs/Lib/ThreadItem.php:206 ../../Zotlabs/Widget/Pinned.php:70 +#: ../../Zotlabs/Lib/ThreadItem.php:229 ../../Zotlabs/Widget/Pinned.php:70 msgid "I will not attend" msgstr "Я не буду участвовать" -#: ../../Zotlabs/Lib/ThreadItem.php:206 ../../Zotlabs/Widget/Pinned.php:70 +#: ../../Zotlabs/Lib/ThreadItem.php:229 ../../Zotlabs/Widget/Pinned.php:70 msgid "I might attend" msgstr "Я возможно буду присутствовать" -#: ../../Zotlabs/Lib/ThreadItem.php:220 ../../Zotlabs/Widget/Pinned.php:81 +#: ../../Zotlabs/Lib/ThreadItem.php:243 ../../Zotlabs/Widget/Pinned.php:81 msgid "I agree" msgstr "Я согласен" -#: ../../Zotlabs/Lib/ThreadItem.php:220 ../../Zotlabs/Widget/Pinned.php:81 +#: ../../Zotlabs/Lib/ThreadItem.php:243 ../../Zotlabs/Widget/Pinned.php:81 msgid "I disagree" msgstr "Я не согласен" -#: ../../Zotlabs/Lib/ThreadItem.php:220 ../../Zotlabs/Widget/Pinned.php:81 +#: ../../Zotlabs/Lib/ThreadItem.php:243 ../../Zotlabs/Widget/Pinned.php:81 msgid "I abstain" msgstr "Я воздержался" -#: ../../Zotlabs/Lib/ThreadItem.php:274 ../../include/conversation.php:736 +#: ../../Zotlabs/Lib/ThreadItem.php:297 ../../include/conversation.php:736 msgid "Toggle Star Status" msgstr "Переключить статус пометки" -#: ../../Zotlabs/Lib/ThreadItem.php:285 ../../Zotlabs/Widget/Pinned.php:88 +#: ../../Zotlabs/Lib/ThreadItem.php:308 ../../Zotlabs/Widget/Pinned.php:88 #: ../../include/conversation.php:751 msgid "Message signature validated" msgstr "Подпись сообщения проверена" -#: ../../Zotlabs/Lib/ThreadItem.php:286 ../../Zotlabs/Widget/Pinned.php:89 +#: ../../Zotlabs/Lib/ThreadItem.php:309 ../../Zotlabs/Widget/Pinned.php:89 #: ../../include/conversation.php:752 msgid "Message signature incorrect" msgstr "Подпись сообщения неверная" -#: ../../Zotlabs/Lib/ThreadItem.php:302 ../../include/conversation.php:943 +#: ../../Zotlabs/Lib/ThreadItem.php:325 ../../include/conversation.php:943 msgid "Conversation Features" msgstr "Возможности бесед" -#: ../../Zotlabs/Lib/ThreadItem.php:318 ../../include/taxonomy.php:584 +#: ../../Zotlabs/Lib/ThreadItem.php:341 ../../include/taxonomy.php:584 msgid "like" msgstr "нравится" -#: ../../Zotlabs/Lib/ThreadItem.php:319 ../../include/taxonomy.php:585 +#: ../../Zotlabs/Lib/ThreadItem.php:342 ../../include/taxonomy.php:585 msgid "dislike" msgstr "не нравится" -#: ../../Zotlabs/Lib/ThreadItem.php:320 +#: ../../Zotlabs/Lib/ThreadItem.php:343 msgid "Reply on this comment" msgstr "Ответить на этот комментарий" -#: ../../Zotlabs/Lib/ThreadItem.php:320 +#: ../../Zotlabs/Lib/ThreadItem.php:343 msgid "reply" msgstr "ответить" -#: ../../Zotlabs/Lib/ThreadItem.php:320 +#: ../../Zotlabs/Lib/ThreadItem.php:343 msgid "Reply to" msgstr "Ответить" -#: ../../Zotlabs/Lib/ThreadItem.php:330 ../../Zotlabs/Widget/Pinned.php:99 +#: ../../Zotlabs/Lib/ThreadItem.php:353 ../../Zotlabs/Widget/Pinned.php:99 msgid "Share This" msgstr "Поделиться этим" -#: ../../Zotlabs/Lib/ThreadItem.php:330 ../../Zotlabs/Widget/Pinned.php:99 +#: ../../Zotlabs/Lib/ThreadItem.php:353 ../../Zotlabs/Widget/Pinned.php:99 msgid "share" msgstr "поделиться" -#: ../../Zotlabs/Lib/ThreadItem.php:340 +#: ../../Zotlabs/Lib/ThreadItem.php:363 msgid "Delivery Report" msgstr "Отчёт о доставке" -#: ../../Zotlabs/Lib/ThreadItem.php:359 +#: ../../Zotlabs/Lib/ThreadItem.php:382 #, php-format msgid "%d comment" msgid_plural "%d comments" @@ -8449,148 +8584,148 @@ msgstr[0] "%d комментарий" msgstr[1] "%d комментария" msgstr[2] "%d комментариев" -#: ../../Zotlabs/Lib/ThreadItem.php:360 +#: ../../Zotlabs/Lib/ThreadItem.php:383 #, php-format msgid "%d unseen" msgstr "новых %d" -#: ../../Zotlabs/Lib/ThreadItem.php:413 +#: ../../Zotlabs/Lib/ThreadItem.php:436 msgid "to" msgstr "к" -#: ../../Zotlabs/Lib/ThreadItem.php:414 ../../Zotlabs/Widget/Messages.php:99 +#: ../../Zotlabs/Lib/ThreadItem.php:437 ../../Zotlabs/Widget/Messages.php:99 #: ../../Zotlabs/Widget/Pinned.php:127 msgid "via" msgstr "через" -#: ../../Zotlabs/Lib/ThreadItem.php:415 +#: ../../Zotlabs/Lib/ThreadItem.php:438 msgid "Wall-to-Wall" msgstr "Стена-на-Стену" -#: ../../Zotlabs/Lib/ThreadItem.php:416 +#: ../../Zotlabs/Lib/ThreadItem.php:439 msgid "via Wall-To-Wall:" msgstr "через Стена-на-Стену:" -#: ../../Zotlabs/Lib/ThreadItem.php:430 ../../Zotlabs/Widget/Pinned.php:132 +#: ../../Zotlabs/Lib/ThreadItem.php:453 ../../Zotlabs/Widget/Pinned.php:132 #: ../../include/conversation.php:817 #, php-format msgid "from %s" msgstr "от %s" -#: ../../Zotlabs/Lib/ThreadItem.php:433 ../../Zotlabs/Widget/Pinned.php:135 +#: ../../Zotlabs/Lib/ThreadItem.php:456 ../../Zotlabs/Widget/Pinned.php:135 #: ../../include/conversation.php:820 #, php-format msgid "last edited: %s" msgstr "последнее редактирование: %s" -#: ../../Zotlabs/Lib/ThreadItem.php:434 ../../Zotlabs/Widget/Pinned.php:136 +#: ../../Zotlabs/Lib/ThreadItem.php:457 ../../Zotlabs/Widget/Pinned.php:136 #: ../../include/conversation.php:821 #, php-format msgid "Expires: %s" msgstr "Срок действия: %s" -#: ../../Zotlabs/Lib/ThreadItem.php:444 +#: ../../Zotlabs/Lib/ThreadItem.php:467 msgid "Attend" msgstr "Посетить" -#: ../../Zotlabs/Lib/ThreadItem.php:445 ../../Zotlabs/Widget/Pinned.php:141 +#: ../../Zotlabs/Lib/ThreadItem.php:468 ../../Zotlabs/Widget/Pinned.php:141 msgid "Attendance Options" msgstr "Параметры посещаемости" -#: ../../Zotlabs/Lib/ThreadItem.php:446 ../../include/text.php:1921 +#: ../../Zotlabs/Lib/ThreadItem.php:469 ../../include/text.php:1946 msgid "Vote" msgstr "Голосовать" -#: ../../Zotlabs/Lib/ThreadItem.php:447 ../../Zotlabs/Widget/Pinned.php:142 +#: ../../Zotlabs/Lib/ThreadItem.php:470 ../../Zotlabs/Widget/Pinned.php:142 msgid "Voting Options" msgstr "Параметры голосования" -#: ../../Zotlabs/Lib/ThreadItem.php:462 +#: ../../Zotlabs/Lib/ThreadItem.php:485 msgid "Go to previous comment" msgstr "Перейти к предыдущему комментарию" -#: ../../Zotlabs/Lib/ThreadItem.php:471 ../../Zotlabs/Widget/Pinned.php:154 +#: ../../Zotlabs/Lib/ThreadItem.php:494 ../../Zotlabs/Widget/Pinned.php:154 msgid "Pinned post" msgstr "Прикреплённая заметка" -#: ../../Zotlabs/Lib/ThreadItem.php:473 ../../Zotlabs/Widget/Pinned.php:155 +#: ../../Zotlabs/Lib/ThreadItem.php:496 ../../Zotlabs/Widget/Pinned.php:155 #: ../../include/js_strings.php:39 msgid "Unpin from the top" msgstr "Открепить" -#: ../../Zotlabs/Lib/ThreadItem.php:473 ../../include/js_strings.php:38 +#: ../../Zotlabs/Lib/ThreadItem.php:496 ../../include/js_strings.php:38 msgid "Pin to the top" msgstr "Прикрепить сверху" -#: ../../Zotlabs/Lib/ThreadItem.php:474 +#: ../../Zotlabs/Lib/ThreadItem.php:497 #: ../../extend/addon/hzaddons/bookmarker/bookmarker.php:38 msgid "Save Bookmarks" msgstr "Сохранить в закладках" -#: ../../Zotlabs/Lib/ThreadItem.php:475 +#: ../../Zotlabs/Lib/ThreadItem.php:498 msgid "Add to Calendar" msgstr "Добавить в календарь" -#: ../../Zotlabs/Lib/ThreadItem.php:502 ../../include/conversation.php:516 +#: ../../Zotlabs/Lib/ThreadItem.php:525 ../../include/conversation.php:516 msgid "This is an unsaved preview" msgstr "Это несохранённый просмотр" -#: ../../Zotlabs/Lib/ThreadItem.php:535 ../../include/js_strings.php:7 +#: ../../Zotlabs/Lib/ThreadItem.php:558 ../../include/js_strings.php:7 #, php-format msgid "%s show all" msgstr "%s показать всё" -#: ../../Zotlabs/Lib/ThreadItem.php:828 ../../include/conversation.php:1455 +#: ../../Zotlabs/Lib/ThreadItem.php:851 ../../include/conversation.php:1469 #: ../../extend/addon/hzaddons/hsse/hsse.php:200 msgid "Bold" msgstr "Жирный" -#: ../../Zotlabs/Lib/ThreadItem.php:829 ../../include/conversation.php:1456 +#: ../../Zotlabs/Lib/ThreadItem.php:852 ../../include/conversation.php:1470 #: ../../extend/addon/hzaddons/hsse/hsse.php:201 msgid "Italic" msgstr "Курсив" -#: ../../Zotlabs/Lib/ThreadItem.php:830 ../../include/conversation.php:1457 +#: ../../Zotlabs/Lib/ThreadItem.php:853 ../../include/conversation.php:1471 #: ../../extend/addon/hzaddons/hsse/hsse.php:202 msgid "Underline" msgstr "Подчеркнутый" -#: ../../Zotlabs/Lib/ThreadItem.php:831 ../../include/conversation.php:1458 +#: ../../Zotlabs/Lib/ThreadItem.php:854 ../../include/conversation.php:1472 #: ../../extend/addon/hzaddons/hsse/hsse.php:203 msgid "Quote" msgstr "Цитата" -#: ../../Zotlabs/Lib/ThreadItem.php:832 ../../include/conversation.php:1459 +#: ../../Zotlabs/Lib/ThreadItem.php:855 ../../include/conversation.php:1473 #: ../../extend/addon/hzaddons/hsse/hsse.php:204 msgid "Code" msgstr "Код" -#: ../../Zotlabs/Lib/ThreadItem.php:833 +#: ../../Zotlabs/Lib/ThreadItem.php:856 msgid "Image" msgstr "Изображение" -#: ../../Zotlabs/Lib/ThreadItem.php:834 ../../include/conversation.php:1460 +#: ../../Zotlabs/Lib/ThreadItem.php:857 ../../include/conversation.php:1474 #: ../../extend/addon/hzaddons/hsse/hsse.php:205 msgid "Attach/Upload file" msgstr "Прикрепить/загрузить файл" -#: ../../Zotlabs/Lib/ThreadItem.php:835 +#: ../../Zotlabs/Lib/ThreadItem.php:858 msgid "Insert Link" msgstr "Вставить ссылку" -#: ../../Zotlabs/Lib/ThreadItem.php:836 +#: ../../Zotlabs/Lib/ThreadItem.php:859 msgid "Video" msgstr "Видео" -#: ../../Zotlabs/Lib/ThreadItem.php:846 +#: ../../Zotlabs/Lib/ThreadItem.php:869 msgid "Your full name (required)" msgstr "Ваше полное имя (требуется)" -#: ../../Zotlabs/Lib/ThreadItem.php:847 +#: ../../Zotlabs/Lib/ThreadItem.php:870 msgid "Your email address (required)" msgstr "Ваш адрес электронной почты (требуется)" -#: ../../Zotlabs/Lib/ThreadItem.php:848 +#: ../../Zotlabs/Lib/ThreadItem.php:871 msgid "Your website URL (optional)" msgstr "URL вашего вебсайта (необязательно)" @@ -8615,12 +8750,8 @@ msgstr "Только этот веб-сайт" msgid "Visible to your default audience" msgstr "Видно вашей аудитории по умолчанию." -#: ../../Zotlabs/Lib/PermissionDescription.php:107 -#: ../../include/acl_selectors.php:136 -msgid "Only me" -msgstr "Только мне" - #: ../../Zotlabs/Lib/PermissionDescription.php:108 +#: ../../Zotlabs/Access/PermissionRoles.php:384 msgid "Public" msgstr "Общедоступно" @@ -8673,45 +8804,45 @@ msgstr "Это настройка по умолчанию для тех, кто msgid "This is your default setting for the audience of your webpages" msgstr "Это настройка по умолчанию для аудитории ваших веб-страниц" -#: ../../Zotlabs/Lib/Activity.php:2213 +#: ../../Zotlabs/Lib/Activity.php:2285 #, php-format msgid "Likes %1$s's %2$s" msgstr "Нравится %1$s %2$s" -#: ../../Zotlabs/Lib/Activity.php:2216 +#: ../../Zotlabs/Lib/Activity.php:2288 #, php-format msgid "Doesn't like %1$s's %2$s" msgstr "Не нравится %1$s %2$s" -#: ../../Zotlabs/Lib/Activity.php:2222 +#: ../../Zotlabs/Lib/Activity.php:2294 #, php-format msgid "Will attend %s's event" msgstr "Присоединится к мероприятию %s" -#: ../../Zotlabs/Lib/Activity.php:2225 +#: ../../Zotlabs/Lib/Activity.php:2297 #, php-format msgid "Will not attend %s's event" msgstr "Не присоединится к мероприятию %s" -#: ../../Zotlabs/Lib/Activity.php:2228 +#: ../../Zotlabs/Lib/Activity.php:2300 #, php-format msgid "May attend %s's event" msgstr "Возможно присоединится к мероприятию %s" -#: ../../Zotlabs/Lib/Activity.php:2231 +#: ../../Zotlabs/Lib/Activity.php:2303 #, php-format msgid "May not attend %s's event" msgstr "Возможно не присоединится к мероприятию %s" -#: ../../Zotlabs/Lib/Activity.php:3156 ../../Zotlabs/Lib/Activity.php:3348 +#: ../../Zotlabs/Lib/Activity.php:3239 ../../Zotlabs/Lib/Activity.php:3431 #: ../../include/network.php:1742 -#: ../../extend/addon/hzaddons/pubcrawl/as.php:1338 -#: ../../extend/addon/hzaddons/pubcrawl/as.php:1778 -#: ../../extend/addon/hzaddons/pubcrawl/as.php:1986 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1332 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1776 +#: ../../extend/addon/hzaddons/pubcrawl/as.php:1987 msgid "ActivityPub" msgstr "" -#: ../../Zotlabs/Lib/Apps.php:329 ../../include/nav.php:333 +#: ../../Zotlabs/Lib/Apps.php:329 ../../include/nav.php:331 msgid "Apps" msgstr "Приложения" @@ -8729,7 +8860,7 @@ msgid "Report Bug" msgstr "Сообщить об ошибке" #: ../../Zotlabs/Lib/Apps.php:336 ../../Zotlabs/Widget/Chatroom_list.php:16 -#: ../../include/nav.php:482 ../../include/nav.php:485 +#: ../../include/nav.php:480 ../../include/nav.php:483 msgid "Chatrooms" msgstr "Чаты" @@ -8758,7 +8889,7 @@ msgstr "Менеджер каналов" msgid "Stream" msgstr "Поток" -#: ../../Zotlabs/Lib/Apps.php:348 ../../include/nav.php:544 +#: ../../Zotlabs/Lib/Apps.php:348 ../../include/nav.php:542 msgid "Wiki" msgstr "" @@ -8766,8 +8897,8 @@ msgstr "" msgid "Channel Home" msgstr "Главная канала" -#: ../../Zotlabs/Lib/Apps.php:352 ../../include/nav.php:468 -#: ../../include/nav.php:471 ../../include/features.php:82 +#: ../../Zotlabs/Lib/Apps.php:352 ../../include/nav.php:466 +#: ../../include/nav.php:469 ../../include/features.php:82 msgid "Calendar" msgstr "Календарь" @@ -8835,7 +8966,7 @@ msgstr "" msgid "Guest Access" msgstr "Гостевой доступ" -#: ../../Zotlabs/Lib/Apps.php:376 ../../Zotlabs/Widget/Notes.php:21 +#: ../../Zotlabs/Lib/Apps.php:376 ../../Zotlabs/Widget/Notes.php:26 #: ../../extend/addon/hzaddons/workflow/workflow.php:2625 msgid "Notes" msgstr "Записки" @@ -8852,6 +8983,10 @@ msgstr "Менеджер OAuth2" msgid "PDL Editor" msgstr "Редактор PDL" +#: ../../Zotlabs/Lib/Apps.php:380 +msgid "Permission Categories" +msgstr "Категории разрешений" + #: ../../Zotlabs/Lib/Apps.php:382 msgid "My Chatrooms" msgstr "Мои чаты" @@ -8884,32 +9019,36 @@ msgstr "Добавить на панель навигации" msgid "Unpin from navbar" msgstr "Удалить с панели навигации" -#: ../../Zotlabs/Lib/AccessList.php:28 +#: ../../Zotlabs/Lib/AccessList.php:26 msgid "" "A deleted list with this name was revived. Existing item permissions " "may apply to this list and any future members. If this is " "not what you intended, please create another list with a different name." msgstr "Восстановлен удаленный список с таким именем. Существующие разрешения на элементы могут применяться к этому списку и любым будущим участникам. Если не отвечает вашим намерениям - создайте еще один список с другим именем." -#: ../../Zotlabs/Lib/AccessList.php:286 -msgid "Add new connections to this access list" -msgstr "Добавить новый контакт в список доступа" +#: ../../Zotlabs/Lib/AccessList.php:265 +msgid "Select a privacy group" +msgstr "Выбрать группу конфиденциальности" -#: ../../Zotlabs/Lib/AccessList.php:331 -msgid "Lists" -msgstr "Списки" +#: ../../Zotlabs/Lib/AccessList.php:329 ../../include/group.php:305 +msgid "edit" +msgstr "редактировать" + +#: ../../Zotlabs/Lib/AccessList.php:350 ../../include/group.php:328 +msgid "Edit group" +msgstr "Редактировать группу" -#: ../../Zotlabs/Lib/AccessList.php:332 -msgid "Edit list" -msgstr "Редактировать список" +#: ../../Zotlabs/Lib/AccessList.php:351 +msgid "Create new group" +msgstr "Создать новую группу" -#: ../../Zotlabs/Lib/AccessList.php:333 -msgid "Create new list" -msgstr "Создать новый список" +#: ../../Zotlabs/Lib/AccessList.php:352 ../../include/group.php:330 +msgid "Channels not in any privacy group" +msgstr "Каналы не включены ни в одну группу конфиденциальности" -#: ../../Zotlabs/Lib/AccessList.php:334 -msgid "Channels not in any access list" -msgstr "Каналы, не входящие ни в один список доступа" +#: ../../Zotlabs/Lib/AccessList.php:354 +msgid "Add" +msgstr "Добавить" #: ../../Zotlabs/Lib/Enotify.php:60 msgid "$Projectname Notification" @@ -9279,99 +9418,96 @@ msgstr "4. Эксперт - я умею программировать" msgid "5. Wizard - I probably know more than you do" msgstr "5. Волшебник - возможно я знаю больше чем ты" -#: ../../Zotlabs/Lib/Permcat.php:82 -msgctxt "permcat" -msgid "default" -msgstr "по умолчанию" - -#: ../../Zotlabs/Lib/Permcat.php:133 -msgctxt "permcat" -msgid "follower" -msgstr "поклонник" - -#: ../../Zotlabs/Lib/Permcat.php:137 -msgctxt "permcat" -msgid "contributor" -msgstr "участник" - -#: ../../Zotlabs/Lib/Permcat.php:141 +#: ../../Zotlabs/Lib/Permcat.php:84 msgctxt "permcat" -msgid "publisher" -msgstr "издатель" +msgid "Default" +msgstr "По умолчанию" -#: ../../Zotlabs/Lib/Libsync.php:750 +#: ../../Zotlabs/Lib/Libsync.php:748 #, php-format msgid "Unable to verify site signature for %s" msgstr "Невозможно проверить подпись сайта %s" -#: ../../Zotlabs/Lib/Libzot.php:671 +#: ../../Zotlabs/Lib/Libzot.php:673 msgid "Unable to verify channel signature" msgstr "Невозможно проверить подпись канала" -#: ../../Zotlabs/Access/PermissionRoles.php:287 +#: ../../Zotlabs/Access/PermissionRoles.php:337 msgid "Social Networking" msgstr "Социальная Сеть" -#: ../../Zotlabs/Access/PermissionRoles.php:288 +#: ../../Zotlabs/Access/PermissionRoles.php:338 msgid "Social - Federation" msgstr "Социальная - Федерация" -#: ../../Zotlabs/Access/PermissionRoles.php:289 +#: ../../Zotlabs/Access/PermissionRoles.php:339 msgid "Social - Mostly Public" msgstr "Социальная - В основном общественный" -#: ../../Zotlabs/Access/PermissionRoles.php:290 +#: ../../Zotlabs/Access/PermissionRoles.php:340 msgid "Social - Restricted" msgstr "Социальная - Ограниченный" -#: ../../Zotlabs/Access/PermissionRoles.php:291 +#: ../../Zotlabs/Access/PermissionRoles.php:341 msgid "Social - Private" msgstr "Социальная - Частный" -#: ../../Zotlabs/Access/PermissionRoles.php:294 +#: ../../Zotlabs/Access/PermissionRoles.php:344 msgid "Community Forum" msgstr "Форум сообщества" -#: ../../Zotlabs/Access/PermissionRoles.php:295 +#: ../../Zotlabs/Access/PermissionRoles.php:345 msgid "Forum - Mostly Public" msgstr "Форум - В основном общественный" -#: ../../Zotlabs/Access/PermissionRoles.php:296 +#: ../../Zotlabs/Access/PermissionRoles.php:346 msgid "Forum - Restricted" msgstr "Форум - Ограниченный" -#: ../../Zotlabs/Access/PermissionRoles.php:297 +#: ../../Zotlabs/Access/PermissionRoles.php:347 msgid "Forum - Private" msgstr "Форум - Частный" -#: ../../Zotlabs/Access/PermissionRoles.php:300 +#: ../../Zotlabs/Access/PermissionRoles.php:350 msgid "Feed Republish" msgstr "Публиковать ленты новостей" -#: ../../Zotlabs/Access/PermissionRoles.php:301 +#: ../../Zotlabs/Access/PermissionRoles.php:351 msgid "Feed - Mostly Public" msgstr "Ленты новостей - В основном общественный" -#: ../../Zotlabs/Access/PermissionRoles.php:302 +#: ../../Zotlabs/Access/PermissionRoles.php:352 msgid "Feed - Restricted" msgstr "Ленты новостей - Ограниченный" -#: ../../Zotlabs/Access/PermissionRoles.php:305 +#: ../../Zotlabs/Access/PermissionRoles.php:355 msgid "Special Purpose" msgstr "Спец. назначение" -#: ../../Zotlabs/Access/PermissionRoles.php:306 +#: ../../Zotlabs/Access/PermissionRoles.php:356 msgid "Special - Celebrity/Soapbox" msgstr "Спец. назначение - Знаменитость/Soapbox" -#: ../../Zotlabs/Access/PermissionRoles.php:307 +#: ../../Zotlabs/Access/PermissionRoles.php:357 msgid "Special - Group Repository" msgstr "Спец. назначение - Групповой репозиторий" -#: ../../Zotlabs/Access/PermissionRoles.php:311 +#: ../../Zotlabs/Access/PermissionRoles.php:361 msgid "Custom/Expert Mode" msgstr "Экспертный режим" +#: ../../Zotlabs/Access/PermissionRoles.php:385 +msgid "Personal" +msgstr "Личное" + +#: ../../Zotlabs/Access/PermissionRoles.php:386 +msgid "Community forum" +msgstr "Форум сообщества" + +#: ../../Zotlabs/Access/PermissionRoles.php:387 +msgid "Custom" +msgstr "Собственные" + #: ../../Zotlabs/Access/Permissions.php:56 msgid "Can view my channel stream and posts" msgstr "Может просматривать мой поток и сообщения" @@ -9429,16 +9565,12 @@ msgid "Can like/dislike profiles and profile things" msgstr "Может комментировать или отмечать как нравится/ненравится мой профиль" #: ../../Zotlabs/Access/Permissions.php:70 -msgid "Can forward direct messages to all my channel connections (forum)" -msgstr "Может пересылать личные сообщения всем своим контактам (форум)" - -#: ../../Zotlabs/Access/Permissions.php:71 msgid "Can chat with me" msgstr "Может общаться со мной в чате" -#: ../../Zotlabs/Access/Permissions.php:72 -msgid "Can source my public posts in derived channels" -msgstr "Может использовать мои публичные сообщения в клонированных лентах сообщений" +#: ../../Zotlabs/Access/Permissions.php:71 +msgid "Can source/mirror my public posts in derived channels" +msgstr "Могу ли я создавать / зеркалировать мои общедоступные сообщения в производных каналах" #: ../../Zotlabs/Access/Permissions.php:73 msgid "Can administer my channel" @@ -9552,7 +9684,7 @@ msgstr "Просмотр очереди" msgid "DB updates" msgstr "Обновление базы данных" -#: ../../Zotlabs/Widget/Admin.php:55 ../../include/nav.php:198 +#: ../../Zotlabs/Widget/Admin.php:55 ../../include/nav.php:196 msgid "Admin" msgstr "Администрирование" @@ -9847,7 +9979,7 @@ msgstr "Загрузить фотографию профиля" msgid "Upload cover photo" msgstr "Загрузить фотографию обложки" -#: ../../Zotlabs/Widget/Newmember.php:35 ../../include/nav.php:117 +#: ../../Zotlabs/Widget/Newmember.php:35 ../../include/nav.php:115 msgid "Edit your profile" msgstr "Редактировать профиль" @@ -9931,6 +10063,10 @@ msgstr "Удалить выражение" msgid "Saved Searches" msgstr "Сохранённые поиски" +#: ../../Zotlabs/Widget/Savedsearch.php:84 ../../include/group.php:332 +msgid "add" +msgstr "добавить" + #: ../../Zotlabs/Widget/Messages.php:24 msgid "Public and restricted messages" msgstr "Общедоступные и частные публикации" @@ -9947,6 +10083,26 @@ msgstr "Отмеченные публикации" msgid "No messages" msgstr "Сообщений нет" +#: ../../Zotlabs/Widget/Notes.php:27 +msgid "Read mode" +msgstr "Читать дальше" + +#: ../../Zotlabs/Widget/Notes.php:28 +msgid "Edit mode" +msgstr "Режим редактирования" + +#: ../../Zotlabs/Widget/Notes.php:29 +msgid "Editing" +msgstr "Редактируем" + +#: ../../Zotlabs/Widget/Notes.php:30 +msgid "Saving" +msgstr "Сохраняем" + +#: ../../Zotlabs/Widget/Notes.php:31 +msgid "Saved" +msgstr "Сохранено" + #: ../../Zotlabs/Widget/Mailmenu.php:13 msgid "Private Mail Menu" msgstr "Меню личной переписки" @@ -9963,6 +10119,10 @@ msgstr "Входящие" msgid "Outbox" msgstr "Исходящие" +#: ../../Zotlabs/Widget/Permcats.php:81 +msgid "Role members" +msgstr "Обладатели роли" + #: ../../Zotlabs/Widget/Rating.php:51 msgid "Rating Tools" msgstr "Инструменты оценки" @@ -9989,11 +10149,6 @@ msgstr "Активность" msgid "App Categories" msgstr "Категории приложений" -#: ../../Zotlabs/Widget/Follow.php:22 -#, php-format -msgid "You have %1$.0f of %2$.0f allowed connections." -msgstr "У вас есть %1$.0f из %2$.0f разрешенных контактов." - #: ../../Zotlabs/Widget/Follow.php:29 msgid "Add New Connection" msgstr "Добавить новый контакт" @@ -10044,11 +10199,15 @@ msgstr "Настройки аккаунта" msgid "Channel settings" msgstr "Настройки канала" -#: ../../Zotlabs/Widget/Settings_menu.php:46 +#: ../../Zotlabs/Widget/Settings_menu.php:44 +msgid "Privacy settings" +msgstr "Настройки конфиденциальности" + +#: ../../Zotlabs/Widget/Settings_menu.php:51 msgid "Display settings" msgstr "Настройки отображения" -#: ../../Zotlabs/Widget/Settings_menu.php:53 +#: ../../Zotlabs/Widget/Settings_menu.php:58 msgid "Manage locations" msgstr "Управление местоположением" @@ -10105,201 +10264,205 @@ msgstr "В процессе" msgid "Cancelled" msgstr "Отменено" -#: ../../include/event.php:1424 ../../include/connections.php:726 +#: ../../include/event.php:1424 ../../include/connections.php:753 msgid "Home, Voice" msgstr "Дом, голос" -#: ../../include/event.php:1425 ../../include/connections.php:727 +#: ../../include/event.php:1425 ../../include/connections.php:754 msgid "Home, Fax" msgstr "Дом, факс" -#: ../../include/event.php:1427 ../../include/connections.php:729 +#: ../../include/event.php:1427 ../../include/connections.php:756 msgid "Work, Voice" msgstr "Работа, голос" -#: ../../include/event.php:1428 ../../include/connections.php:730 +#: ../../include/event.php:1428 ../../include/connections.php:757 msgid "Work, Fax" msgstr "Работа, факс" -#: ../../include/channel.php:46 +#: ../../include/channel.php:48 msgid "Unable to obtain identity information from database" msgstr "Невозможно получить идентификационную информацию из базы данных" -#: ../../include/channel.php:79 +#: ../../include/channel.php:81 msgid "Empty name" msgstr "Пустое имя" -#: ../../include/channel.php:82 +#: ../../include/channel.php:84 msgid "Name too long" msgstr "Слишком длинное имя" -#: ../../include/channel.php:199 +#: ../../include/channel.php:201 msgid "No account identifier" msgstr "Идентификатор аккаунта отсутствует" -#: ../../include/channel.php:290 +#: ../../include/channel.php:292 msgid "Unable to retrieve created identity" msgstr "Не удается получить созданный идентификатор" -#: ../../include/channel.php:393 +#: ../../include/channel.php:402 msgid "Default Profile" msgstr "Профиль по умолчанию" -#: ../../include/channel.php:590 ../../include/channel.php:679 +#: ../../include/channel.php:592 ../../include/channel.php:681 msgid "Unable to retrieve modified identity" msgstr "Не удается найти изменённый идентификатор" -#: ../../include/channel.php:1340 +#: ../../include/channel.php:1373 msgid "Requested channel is not available" msgstr "Запрошенный канал недоступен" -#: ../../include/channel.php:1497 +#: ../../include/channel.php:1531 msgid "Create New Profile" msgstr "Создать новый профиль" -#: ../../include/channel.php:1500 ../../include/nav.php:117 +#: ../../include/channel.php:1534 ../../include/nav.php:115 #: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:59 msgid "Edit Profile" msgstr "Редактировать профиль" -#: ../../include/channel.php:1518 +#: ../../include/channel.php:1552 msgid "Visible to everybody" msgstr "Видно всем" -#: ../../include/channel.php:1595 ../../include/channel.php:1723 +#: ../../include/channel.php:1629 ../../include/channel.php:1758 msgid "Gender:" msgstr "Пол:" -#: ../../include/channel.php:1596 ../../include/channel.php:1767 +#: ../../include/channel.php:1630 ../../include/channel.php:1802 msgid "Status:" msgstr "Статус:" -#: ../../include/channel.php:1597 ../../include/channel.php:1791 +#: ../../include/channel.php:1631 ../../include/channel.php:1826 msgid "Homepage:" msgstr "Домашняя страница:" -#: ../../include/channel.php:1598 +#: ../../include/channel.php:1633 msgid "Online Now" msgstr "Сейчас в сети" -#: ../../include/channel.php:1651 +#: ../../include/channel.php:1686 msgid "Change your profile photo" msgstr "Изменить фотографию вашего профиля" -#: ../../include/channel.php:1678 ../../include/selectors.php:60 +#: ../../include/channel.php:1713 ../../include/selectors.php:60 #: ../../include/selectors.php:77 #: ../../extend/addon/hzaddons/openid/Mod_Id.php:87 msgid "Female" msgstr "Женщина" -#: ../../include/channel.php:1680 ../../include/selectors.php:60 +#: ../../include/channel.php:1715 ../../include/selectors.php:60 #: ../../include/selectors.php:77 #: ../../extend/addon/hzaddons/openid/Mod_Id.php:85 msgid "Male" msgstr "Мужчина" -#: ../../include/channel.php:1682 +#: ../../include/channel.php:1717 msgid "Trans" msgstr "Трансексуал" -#: ../../include/channel.php:1684 ../../include/selectors.php:60 +#: ../../include/channel.php:1719 ../../include/selectors.php:60 msgid "Neuter" msgstr "Среднего рода" -#: ../../include/channel.php:1686 ../../include/selectors.php:60 +#: ../../include/channel.php:1721 ../../include/selectors.php:60 msgid "Non-specific" msgstr "Неспецифический" -#: ../../include/channel.php:1728 +#: ../../include/channel.php:1756 +msgid "Full Name:" +msgstr "Полное имя:" + +#: ../../include/channel.php:1763 msgid "Like this channel" msgstr "нравится этот канал" -#: ../../include/channel.php:1752 +#: ../../include/channel.php:1787 msgid "j F, Y" msgstr "" -#: ../../include/channel.php:1753 +#: ../../include/channel.php:1788 msgid "j F" msgstr "" -#: ../../include/channel.php:1760 +#: ../../include/channel.php:1795 msgid "Birthday:" msgstr "День рождения:" -#: ../../include/channel.php:1773 +#: ../../include/channel.php:1808 #, php-format msgid "for %1$d %2$s" msgstr "для %1$d %2$s" -#: ../../include/channel.php:1785 +#: ../../include/channel.php:1820 msgid "Tags:" msgstr "Теги:" -#: ../../include/channel.php:1789 +#: ../../include/channel.php:1824 msgid "Sexual Preference:" msgstr "Сексуальные предпочтения:" -#: ../../include/channel.php:1795 +#: ../../include/channel.php:1830 msgid "Political Views:" msgstr "Политические взгляды:" -#: ../../include/channel.php:1797 +#: ../../include/channel.php:1832 msgid "Religion:" msgstr "Религия:" -#: ../../include/channel.php:1801 +#: ../../include/channel.php:1836 msgid "Hobbies/Interests:" msgstr "Хобби / интересы:" -#: ../../include/channel.php:1803 +#: ../../include/channel.php:1838 msgid "Likes:" msgstr "Что вам нравится:" -#: ../../include/channel.php:1805 +#: ../../include/channel.php:1840 msgid "Dislikes:" msgstr "Что вам не нравится:" -#: ../../include/channel.php:1807 +#: ../../include/channel.php:1842 msgid "Contact information and Social Networks:" msgstr "Контактная информация и социальные сети:" -#: ../../include/channel.php:1809 +#: ../../include/channel.php:1844 msgid "My other channels:" msgstr "Мои другие каналы:" -#: ../../include/channel.php:1811 +#: ../../include/channel.php:1846 msgid "Musical interests:" msgstr "Музыкальные интересы:" -#: ../../include/channel.php:1813 +#: ../../include/channel.php:1848 msgid "Books, literature:" msgstr "Книги, литература:" -#: ../../include/channel.php:1815 +#: ../../include/channel.php:1850 msgid "Television:" msgstr "Телевидение:" -#: ../../include/channel.php:1817 +#: ../../include/channel.php:1852 msgid "Film/dance/culture/entertainment:" msgstr "Кино / танцы / культура / развлечения:" -#: ../../include/channel.php:1819 +#: ../../include/channel.php:1854 msgid "Love/Romance:" msgstr "Любовь / романтика:" -#: ../../include/channel.php:1821 +#: ../../include/channel.php:1856 msgid "Work/employment:" msgstr "Работа / занятость:" -#: ../../include/channel.php:1823 +#: ../../include/channel.php:1858 msgid "School/education:" msgstr "Школа / образование:" -#: ../../include/channel.php:1846 +#: ../../include/channel.php:1881 msgid "Like this thing" msgstr "нравится этo" -#: ../../include/channel.php:1847 +#: ../../include/channel.php:1882 msgid "Export" msgstr "Экспорт" @@ -10414,7 +10577,7 @@ msgstr "День рождения %1$s" msgid "Happy Birthday %1$s" msgstr "С Днем рождения %1$s !" -#: ../../include/language.php:428 ../../include/text.php:2095 +#: ../../include/language.php:428 ../../include/text.php:2123 msgid "default" msgstr "по умолчанию" @@ -10462,7 +10625,7 @@ msgstr "Помощь:" msgid "Not Found" msgstr "Не найдено" -#: ../../include/zid.php:403 +#: ../../include/zid.php:406 #, php-format msgid "OpenWebAuth: %1$s welcomes %2$s" msgstr "OpenWebAuth: %1$s приветствует %2$s" @@ -10487,34 +10650,34 @@ msgstr "Встроенное содержимое" msgid "Embedding disabled" msgstr "Встраивание отключено" -#: ../../include/photos.php:154 +#: ../../include/photos.php:153 #, php-format msgid "Image exceeds website size limit of %lu bytes" msgstr "Файл превышает предельный размер для сайта в %lu байт" -#: ../../include/photos.php:165 +#: ../../include/photos.php:164 msgid "Image file is empty." msgstr "Файл изображения пуст." -#: ../../include/photos.php:327 +#: ../../include/photos.php:324 msgid "Photo storage failed." msgstr "Ошибка хранилища фотографий." -#: ../../include/photos.php:376 +#: ../../include/photos.php:373 msgid "a new photo" msgstr "новая фотография" -#: ../../include/photos.php:380 +#: ../../include/photos.php:377 #, php-format msgctxt "photo_upload" msgid "%1$s posted %2$s to %3$s" msgstr "%1$s опубликовал %2$s в %3$s" -#: ../../include/photos.php:714 ../../include/nav.php:452 +#: ../../include/photos.php:722 ../../include/nav.php:450 msgid "Photo Albums" msgstr "Фотоальбомы" -#: ../../include/photos.php:719 +#: ../../include/photos.php:727 msgid "Upload New Photos" msgstr "Загрузить новые фотографии" @@ -10523,14 +10686,29 @@ msgstr "Загрузить новые фотографии" msgid "This is the home page of %s." msgstr "Это домашняя страница %s." -#: ../../include/connections.php:134 +#: ../../include/connections.php:136 msgid "New window" msgstr "Новое окно" -#: ../../include/connections.php:135 +#: ../../include/connections.php:137 msgid "Open the selected location in a different window or browser tab" msgstr "Открыть выбранное местоположение в другом окне или вкладке браузера" +#: ../../include/group.php:23 +msgid "" +"A deleted group with this name was revived. Existing item permissions " +"may apply to this group and any future members. If this is " +"not what you intended, please create another group with a different name." +msgstr "Удаленная группа с этим названием была восстановлена. Существующие разрешения пункт могут применяться к этой группе и к её будущих участников. Если это не то, чего вы хотели, пожалуйста, создайте другую группу с другим именем." + +#: ../../include/group.php:271 +msgid "Add new connections to this privacy group" +msgstr "Добавить новые контакты в группу конфиденциальности" + +#: ../../include/group.php:329 +msgid "Manage privacy groups" +msgstr "Управлять группами конфиденциальности" + #: ../../include/auth.php:194 msgid "Delegation session ended." msgstr "Делегированная сессия завершена." @@ -10548,7 +10726,7 @@ msgid "Failed authentication" msgstr "Ошибка аутентификации" #: ../../include/auth.php:320 -#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:188 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:189 msgid "Login failed." msgstr "Не удалось войти." @@ -10565,106 +10743,102 @@ msgid "Manage your channels" msgstr "Управление вашими каналами" #: ../../include/nav.php:101 -msgid "Manage your privacy groups" -msgstr "Управление вашим группами конфиденциальности" - -#: ../../include/nav.php:103 msgid "Account/Channel Settings" msgstr "Настройки аккаунта / канала" -#: ../../include/nav.php:109 ../../include/nav.php:139 +#: ../../include/nav.php:107 ../../include/nav.php:137 msgid "End this session" msgstr "Закончить эту сессию" -#: ../../include/nav.php:112 +#: ../../include/nav.php:110 msgid "Your profile page" msgstr "Страницa вашего профиля" -#: ../../include/nav.php:115 +#: ../../include/nav.php:113 msgid "Manage/Edit profiles" msgstr "Управление / редактирование профилей" -#: ../../include/nav.php:124 ../../include/nav.php:128 +#: ../../include/nav.php:122 ../../include/nav.php:126 msgid "Sign in" msgstr "Войти" -#: ../../include/nav.php:158 +#: ../../include/nav.php:156 msgid "Take me home" msgstr "Домой" -#: ../../include/nav.php:160 +#: ../../include/nav.php:158 msgid "Log me out of this site" msgstr "Выйти с этого сайта" -#: ../../include/nav.php:165 +#: ../../include/nav.php:163 msgid "Create an account" msgstr "Создать аккаунт" -#: ../../include/nav.php:178 +#: ../../include/nav.php:176 msgid "Help and documentation" msgstr "Справочная информация и документация" -#: ../../include/nav.php:192 +#: ../../include/nav.php:190 msgid "Search site @name, !forum, #tag, ?docs, content" msgstr "Искать на сайте @имя, !форум, #тег, ?документ, содержимое" -#: ../../include/nav.php:198 +#: ../../include/nav.php:196 msgid "Site Setup and Configuration" msgstr "Установка и конфигурация сайта" -#: ../../include/nav.php:326 +#: ../../include/nav.php:324 msgid "@name, #tag, ?doc, content" msgstr "@имя, #тег, ?документ, содержимое" -#: ../../include/nav.php:327 +#: ../../include/nav.php:325 msgid "Please wait..." msgstr "Подождите пожалуйста ..." -#: ../../include/nav.php:334 +#: ../../include/nav.php:332 msgid "Channel Apps" msgstr "Приложения канала" -#: ../../include/nav.php:335 +#: ../../include/nav.php:333 msgid "System Apps" msgstr "Системные приложения" -#: ../../include/nav.php:336 +#: ../../include/nav.php:334 msgid "Pinned Apps" msgstr "Прикреплённые приложения" -#: ../../include/nav.php:337 +#: ../../include/nav.php:335 msgid "Featured Apps" msgstr "Популярные приложения" -#: ../../include/nav.php:429 +#: ../../include/nav.php:427 msgid "Status Messages and Posts" msgstr "Статусы и публикации" -#: ../../include/nav.php:442 +#: ../../include/nav.php:440 msgid "Profile Details" msgstr "Информация о профиле" -#: ../../include/nav.php:460 +#: ../../include/nav.php:458 msgid "Files and Storage" msgstr "Файлы и хранилище" -#: ../../include/nav.php:498 +#: ../../include/nav.php:496 msgid "Saved Bookmarks" msgstr "Сохранённые закладки" -#: ../../include/nav.php:509 +#: ../../include/nav.php:507 msgid "View Cards" msgstr "Просмотреть карточки" -#: ../../include/nav.php:520 +#: ../../include/nav.php:518 msgid "View Articles" msgstr "Просмотр статей" -#: ../../include/nav.php:532 +#: ../../include/nav.php:530 msgid "View Webpages" msgstr "Просмотр веб-страниц" -#: ../../include/feedutils.php:874 ../../include/text.php:1541 +#: ../../include/feedutils.php:874 ../../include/text.php:1538 msgid "unknown" msgstr "неизвестный" @@ -10717,11 +10891,15 @@ msgstr "%1$s теперь в контакте с %2$s" msgid "%1$s poked %2$s" msgstr "%1$s ткнул %2$s" -#: ../../include/conversation.php:267 ../../include/text.php:1237 -#: ../../include/text.php:1241 +#: ../../include/conversation.php:267 ../../include/text.php:1234 +#: ../../include/text.php:1238 msgid "poked" msgstr "ткнут" +#: ../../include/conversation.php:742 +msgid "Private Message" +msgstr "Личное сообщение" + #: ../../include/conversation.php:789 #, php-format msgid "View %s's profile @ %s" @@ -10763,21 +10941,21 @@ msgstr "Следить за темой" msgid "Unfollow Thread" msgstr "Прекратить отслеживать тему" -#: ../../include/conversation.php:1116 +#: ../../include/conversation.php:1122 msgid "Edit Connection" msgstr "Редактировать контакт" -#: ../../include/conversation.php:1268 +#: ../../include/conversation.php:1282 #, php-format msgid "%s likes this." msgstr "%s нравится это." -#: ../../include/conversation.php:1268 +#: ../../include/conversation.php:1282 #, php-format msgid "%s doesn't like this." msgstr "%s не нравится это." -#: ../../include/conversation.php:1272 +#: ../../include/conversation.php:1286 #, php-format msgid "%2$d people like this." msgid_plural "%2$d people like this." @@ -10785,7 +10963,7 @@ msgstr[0] "%2$d человеку это нравится." msgstr[1] "%2$d человекам это нравится." msgstr[2] "%2$d человекам это нравится." -#: ../../include/conversation.php:1274 +#: ../../include/conversation.php:1288 #, php-format msgid "%2$d people don't like this." msgid_plural "%2$d people don't like this." @@ -10793,11 +10971,11 @@ msgstr[0] "%2$d человеку это не нравится msgstr[1] "%2$d человекам это не нравится." msgstr[2] "%2$d человекам это не нравится." -#: ../../include/conversation.php:1280 +#: ../../include/conversation.php:1294 msgid "and" msgstr "и" -#: ../../include/conversation.php:1283 +#: ../../include/conversation.php:1297 #, php-format msgid ", and %d other people" msgid_plural ", and %d other people" @@ -10805,140 +10983,140 @@ msgstr[0] ", и ещё %d человеку" msgstr[1] ", и ещё %d человекам" msgstr[2] ", и ещё %d человекам" -#: ../../include/conversation.php:1284 +#: ../../include/conversation.php:1298 #, php-format msgid "%s like this." msgstr "%s нравится это." -#: ../../include/conversation.php:1284 +#: ../../include/conversation.php:1298 #, php-format msgid "%s don't like this." msgstr "%s не нравится это." -#: ../../include/conversation.php:1335 +#: ../../include/conversation.php:1349 #: ../../extend/addon/hzaddons/hsse/hsse.php:82 msgid "Set your location" msgstr "Задать своё местоположение" -#: ../../include/conversation.php:1336 +#: ../../include/conversation.php:1350 #: ../../extend/addon/hzaddons/hsse/hsse.php:83 msgid "Clear browser location" msgstr "Очистить местоположение из браузера" -#: ../../include/conversation.php:1352 +#: ../../include/conversation.php:1366 #: ../../extend/addon/hzaddons/hsse/hsse.php:99 msgid "Embed (existing) photo from your photo albums" msgstr "Встроить (существующее) фото из вашего фотоальбома" -#: ../../include/conversation.php:1386 +#: ../../include/conversation.php:1400 #: ../../extend/addon/hzaddons/hsse/hsse.php:135 msgid "Tag term:" msgstr "Теги:" -#: ../../include/conversation.php:1387 +#: ../../include/conversation.php:1401 #: ../../extend/addon/hzaddons/hsse/hsse.php:136 msgid "Where are you right now?" msgstr "Где вы сейчас?" -#: ../../include/conversation.php:1392 +#: ../../include/conversation.php:1406 #: ../../extend/addon/hzaddons/hsse/hsse.php:141 msgid "Choose a different album..." msgstr "Выбрать другой альбом..." -#: ../../include/conversation.php:1396 +#: ../../include/conversation.php:1410 #: ../../extend/addon/hzaddons/hsse/hsse.php:145 msgid "Comments enabled" msgstr "Комментарии включены" -#: ../../include/conversation.php:1397 +#: ../../include/conversation.php:1411 #: ../../extend/addon/hzaddons/hsse/hsse.php:146 msgid "Comments disabled" msgstr "Комментарии отключены" -#: ../../include/conversation.php:1450 +#: ../../include/conversation.php:1464 #: ../../extend/addon/hzaddons/hsse/hsse.php:195 msgid "Page link name" msgstr "Название ссылки на страницу " -#: ../../include/conversation.php:1453 +#: ../../include/conversation.php:1467 #: ../../extend/addon/hzaddons/hsse/hsse.php:198 msgid "Post as" msgstr "Опубликовать как" -#: ../../include/conversation.php:1467 +#: ../../include/conversation.php:1481 #: ../../extend/addon/hzaddons/hsse/hsse.php:212 msgid "Toggle voting" msgstr "Переключить голосование" -#: ../../include/conversation.php:1468 +#: ../../include/conversation.php:1482 msgid "Toggle poll" msgstr "Переключить опрос" -#: ../../include/conversation.php:1469 +#: ../../include/conversation.php:1483 msgid "Option" msgstr "Вариант" -#: ../../include/conversation.php:1470 +#: ../../include/conversation.php:1484 msgid "Add option" msgstr "Добавить вариант" -#: ../../include/conversation.php:1471 +#: ../../include/conversation.php:1485 msgid "Minutes" msgstr "Минут" -#: ../../include/conversation.php:1471 +#: ../../include/conversation.php:1485 msgid "Hours" msgstr "Часов" -#: ../../include/conversation.php:1471 +#: ../../include/conversation.php:1485 msgid "Days" msgstr "Дней" -#: ../../include/conversation.php:1472 +#: ../../include/conversation.php:1486 msgid "Allow multiple answers" msgstr "Разрешить несколько ответов" -#: ../../include/conversation.php:1474 +#: ../../include/conversation.php:1488 #: ../../extend/addon/hzaddons/hsse/hsse.php:215 msgid "Disable comments" msgstr "Отключить комментарии" -#: ../../include/conversation.php:1475 +#: ../../include/conversation.php:1489 #: ../../extend/addon/hzaddons/hsse/hsse.php:216 msgid "Toggle comments" msgstr "Переключить комментарии" -#: ../../include/conversation.php:1482 +#: ../../include/conversation.php:1496 msgid "Summary (optional)" msgstr "Резюме (необязательно)" -#: ../../include/conversation.php:1485 +#: ../../include/conversation.php:1499 #: ../../extend/addon/hzaddons/hsse/hsse.php:224 msgid "Categories (optional, comma-separated list)" msgstr "Категории (необязательно, список через запятую)" -#: ../../include/conversation.php:1486 +#: ../../include/conversation.php:1500 #: ../../extend/addon/hzaddons/hsse/hsse.php:225 msgid "Permission settings" msgstr "Настройки разрешений" -#: ../../include/conversation.php:1508 +#: ../../include/conversation.php:1522 #: ../../extend/addon/hzaddons/hsse/hsse.php:247 msgid "Other networks and post services" msgstr "Другие сети и службы публикаций" -#: ../../include/conversation.php:1511 +#: ../../include/conversation.php:1525 #: ../../extend/addon/hzaddons/hsse/hsse.php:250 #: ../../extend/addon/hzaddons/mail/Mod_Mail.php:209 msgid "Set expiration date" msgstr "Установить срок действия" -#: ../../include/conversation.php:1514 +#: ../../include/conversation.php:1528 #: ../../extend/addon/hzaddons/hsse/hsse.php:253 msgid "Set publish date" msgstr "Установить дату публикации" -#: ../../include/conversation.php:1760 +#: ../../include/conversation.php:1774 msgctxt "noun" msgid "Attending" msgid_plural "Attending" @@ -10946,7 +11124,7 @@ msgstr[0] "Посетит" msgstr[1] "Посетят" msgstr[2] "Посетят" -#: ../../include/conversation.php:1763 +#: ../../include/conversation.php:1777 msgctxt "noun" msgid "Not Attending" msgid_plural "Not Attending" @@ -10954,13 +11132,13 @@ msgstr[0] "Не посетит" msgstr[1] "Не посетят" msgstr[2] "Не посетят" -#: ../../include/conversation.php:1766 +#: ../../include/conversation.php:1780 msgctxt "noun" msgid "Undecided" msgid_plural "Undecided" msgstr "Не решил" -#: ../../include/conversation.php:1769 +#: ../../include/conversation.php:1783 msgctxt "noun" msgid "Agree" msgid_plural "Agrees" @@ -10968,7 +11146,7 @@ msgstr[0] "Согласен" msgstr[1] "Согласны" msgstr[2] "Согласны" -#: ../../include/conversation.php:1772 +#: ../../include/conversation.php:1786 msgctxt "noun" msgid "Disagree" msgid_plural "Disagrees" @@ -10976,7 +11154,7 @@ msgstr[0] "Не согласен" msgstr[1] "Не согласны" msgstr[2] "Не согласны" -#: ../../include/conversation.php:1775 +#: ../../include/conversation.php:1789 msgctxt "noun" msgid "Abstain" msgid_plural "Abstains" @@ -11035,6 +11213,10 @@ msgstr "Здесь нет ничего нового" msgid "Rate This Channel (this is public)" msgstr "Оценкa этoго канала (общедоступно)" +#: ../../include/js_strings.php:20 +msgid "Rating" +msgstr "Оценка" + #: ../../include/js_strings.php:21 msgid "Describe (optional)" msgstr "Охарактеризовать (необязательно)" @@ -11185,19 +11367,19 @@ msgstr " " msgid "timeago.numbers" msgstr "" -#: ../../include/js_strings.php:74 ../../include/text.php:1481 +#: ../../include/js_strings.php:74 ../../include/text.php:1478 msgid "January" msgstr "Январь" -#: ../../include/js_strings.php:75 ../../include/text.php:1481 +#: ../../include/js_strings.php:75 ../../include/text.php:1478 msgid "February" msgstr "Февраль" -#: ../../include/js_strings.php:76 ../../include/text.php:1481 +#: ../../include/js_strings.php:76 ../../include/text.php:1478 msgid "March" msgstr "Март" -#: ../../include/js_strings.php:77 ../../include/text.php:1481 +#: ../../include/js_strings.php:77 ../../include/text.php:1478 msgid "April" msgstr "Апрель" @@ -11206,31 +11388,31 @@ msgctxt "long" msgid "May" msgstr "Май" -#: ../../include/js_strings.php:79 ../../include/text.php:1481 +#: ../../include/js_strings.php:79 ../../include/text.php:1478 msgid "June" msgstr "Июнь" -#: ../../include/js_strings.php:80 ../../include/text.php:1481 +#: ../../include/js_strings.php:80 ../../include/text.php:1478 msgid "July" msgstr "Июль" -#: ../../include/js_strings.php:81 ../../include/text.php:1481 +#: ../../include/js_strings.php:81 ../../include/text.php:1478 msgid "August" msgstr "Август" -#: ../../include/js_strings.php:82 ../../include/text.php:1481 +#: ../../include/js_strings.php:82 ../../include/text.php:1478 msgid "September" msgstr "Сентябрь" -#: ../../include/js_strings.php:83 ../../include/text.php:1481 +#: ../../include/js_strings.php:83 ../../include/text.php:1478 msgid "October" msgstr "Октябрь" -#: ../../include/js_strings.php:84 ../../include/text.php:1481 +#: ../../include/js_strings.php:84 ../../include/text.php:1478 msgid "November" msgstr "Ноябрь" -#: ../../include/js_strings.php:85 ../../include/text.php:1481 +#: ../../include/js_strings.php:85 ../../include/text.php:1478 msgid "December" msgstr "Декабрь" @@ -11283,31 +11465,31 @@ msgstr "Ноя" msgid "Dec" msgstr "Дек" -#: ../../include/js_strings.php:98 ../../include/text.php:1477 +#: ../../include/js_strings.php:98 ../../include/text.php:1474 msgid "Sunday" msgstr "Воскресенье" -#: ../../include/js_strings.php:99 ../../include/text.php:1477 +#: ../../include/js_strings.php:99 ../../include/text.php:1474 msgid "Monday" msgstr "Понедельник" -#: ../../include/js_strings.php:100 ../../include/text.php:1477 +#: ../../include/js_strings.php:100 ../../include/text.php:1474 msgid "Tuesday" msgstr "Вторник" -#: ../../include/js_strings.php:101 ../../include/text.php:1477 +#: ../../include/js_strings.php:101 ../../include/text.php:1474 msgid "Wednesday" msgstr "Среда" -#: ../../include/js_strings.php:102 ../../include/text.php:1477 +#: ../../include/js_strings.php:102 ../../include/text.php:1474 msgid "Thursday" msgstr "Четверг" -#: ../../include/js_strings.php:103 ../../include/text.php:1477 +#: ../../include/js_strings.php:103 ../../include/text.php:1474 msgid "Friday" msgstr "Пятница" -#: ../../include/js_strings.php:104 ../../include/text.php:1477 +#: ../../include/js_strings.php:104 ../../include/text.php:1474 msgid "Saturday" msgstr "Суббота" @@ -11642,8 +11824,8 @@ msgid "Ability to create multiple profiles" msgstr "Возможность создания нескольких профилей" #: ../../include/selectors.php:18 -msgid "Profile to assign new connections" -msgstr "Назначить профиль для новых контактов" +msgid "Select a profile to assign to this contact" +msgstr "Выберите профиль для этого контакта" #: ../../include/selectors.php:41 msgid "Frequently" @@ -11881,67 +12063,72 @@ msgstr "Спроси меня" msgid "(Unknown)" msgstr "(Неизвестный)" -#: ../../include/items.php:1243 +#: ../../include/items.php:1246 msgid "Visible to anybody on the internet." msgstr "Виден всем в интернете." -#: ../../include/items.php:1245 +#: ../../include/items.php:1248 msgid "Visible to you only." msgstr "Видно только вам." -#: ../../include/items.php:1247 +#: ../../include/items.php:1250 msgid "Visible to anybody in this network." msgstr "Видно всем в этой сети." -#: ../../include/items.php:1249 +#: ../../include/items.php:1252 msgid "Visible to anybody authenticated." msgstr "Видно всем аутентифицированным." -#: ../../include/items.php:1251 +#: ../../include/items.php:1254 #, php-format msgid "Visible to anybody on %s." msgstr "Видно всем в %s." -#: ../../include/items.php:1253 +#: ../../include/items.php:1256 msgid "Visible to all connections." msgstr "Видно всем контактам." -#: ../../include/items.php:1255 +#: ../../include/items.php:1258 msgid "Visible to approved connections." msgstr "Видно только одобренным контактам." -#: ../../include/items.php:1257 +#: ../../include/items.php:1260 msgid "Visible to specific connections." msgstr "Видно указанным контактам." -#: ../../include/items.php:4265 +#: ../../include/items.php:4397 msgid "Privacy group is empty." msgstr "Группа конфиденциальности пуста" -#: ../../include/items.php:4272 +#: ../../include/items.php:4404 #, php-format msgid "Privacy group: %s" msgstr "Группа конфиденциальности: %s" -#: ../../include/items.php:4284 +#: ../../include/items.php:4414 +#, php-format +msgid "Connection: %s" +msgstr "Контакт: %s" + +#: ../../include/items.php:4416 msgid "Connection not found." msgstr "Контакт не найден." -#: ../../include/items.php:4637 +#: ../../include/items.php:4769 msgid "profile photo" msgstr "Фотография профиля" -#: ../../include/items.php:4829 +#: ../../include/items.php:4961 #, php-format msgid "[Edited %s]" msgstr "[Отредактировано %s]" -#: ../../include/items.php:4829 +#: ../../include/items.php:4961 msgctxt "edit_activity" msgid "Post" msgstr "Публикация" -#: ../../include/items.php:4829 +#: ../../include/items.php:4961 msgctxt "edit_activity" msgid "Comment" msgstr "Комментарий" @@ -12064,11 +12251,11 @@ msgid "MySpace" msgstr "" #: ../../include/bbcode.php:233 ../../include/bbcode.php:928 -#: ../../include/bbcode.php:1552 ../../include/bbcode.php:1560 +#: ../../include/bbcode.php:1549 ../../include/bbcode.php:1557 msgid "Image/photo" msgstr "Изображение / фотография" -#: ../../include/bbcode.php:280 ../../include/bbcode.php:1577 +#: ../../include/bbcode.php:280 ../../include/bbcode.php:1574 msgid "Encrypted content" msgstr "Зашифрованное содержание" @@ -12113,11 +12300,11 @@ msgstr "Просмотр статьи" msgid "View summary" msgstr "Просмотр резюме" -#: ../../include/bbcode.php:1528 +#: ../../include/bbcode.php:1525 msgid "$1 wrote:" msgstr "$1 писал:" -#: ../../include/security.php:607 +#: ../../include/security.php:625 msgid "" "The form security token was not correct. This probably happened because the " "form has been opened for too long (>3 hours) before submitting it." @@ -12246,311 +12433,325 @@ msgid "" "permissions set who is allowed to view the post." msgstr "Разрешения публикации %s не могут быть изменены %s после того, как ею поделились. Эти разрешения устанавливают кому разрешено просматривать эту публикацию." -#: ../../include/text.php:524 +#: ../../include/text.php:525 msgid "prev" msgstr "предыдущий" -#: ../../include/text.php:526 +#: ../../include/text.php:527 msgid "first" msgstr "первый" -#: ../../include/text.php:555 +#: ../../include/text.php:556 msgid "last" msgstr "последний" -#: ../../include/text.php:558 +#: ../../include/text.php:559 msgid "next" msgstr "следующий" -#: ../../include/text.php:576 +#: ../../include/text.php:577 msgid "older" msgstr "старше" -#: ../../include/text.php:578 +#: ../../include/text.php:579 msgid "newer" msgstr "новее" -#: ../../include/text.php:1019 +#: ../../include/text.php:1016 msgid "No connections" msgstr "Нет контактов" -#: ../../include/text.php:1071 +#: ../../include/text.php:1068 #, php-format msgid "View all %s connections" msgstr "Просмотреть все %s контактов" -#: ../../include/text.php:1134 +#: ../../include/text.php:1131 #, php-format msgid "Network: %s" msgstr "Сеть: %s" -#: ../../include/text.php:1237 ../../include/text.php:1241 +#: ../../include/text.php:1234 ../../include/text.php:1238 msgid "poke" msgstr "Ткнуть" -#: ../../include/text.php:1242 +#: ../../include/text.php:1239 msgid "ping" msgstr "Пингануть" -#: ../../include/text.php:1242 +#: ../../include/text.php:1239 msgid "pinged" msgstr "Отпингован" -#: ../../include/text.php:1243 +#: ../../include/text.php:1240 msgid "prod" msgstr "Подтолкнуть" -#: ../../include/text.php:1243 +#: ../../include/text.php:1240 msgid "prodded" msgstr "Подтолкнут" -#: ../../include/text.php:1244 +#: ../../include/text.php:1241 msgid "slap" msgstr "Шлёпнуть" -#: ../../include/text.php:1244 +#: ../../include/text.php:1241 msgid "slapped" msgstr "Шлёпнут" -#: ../../include/text.php:1245 +#: ../../include/text.php:1242 msgid "finger" msgstr "Указать" -#: ../../include/text.php:1245 +#: ../../include/text.php:1242 msgid "fingered" msgstr "Указан" -#: ../../include/text.php:1246 +#: ../../include/text.php:1243 msgid "rebuff" msgstr "Дать отпор" -#: ../../include/text.php:1246 +#: ../../include/text.php:1243 msgid "rebuffed" msgstr "Дан отпор" -#: ../../include/text.php:1269 +#: ../../include/text.php:1266 msgid "happy" msgstr "счастливый" -#: ../../include/text.php:1270 +#: ../../include/text.php:1267 msgid "sad" msgstr "грустный" -#: ../../include/text.php:1271 +#: ../../include/text.php:1268 msgid "mellow" msgstr "спокойный" -#: ../../include/text.php:1272 +#: ../../include/text.php:1269 msgid "tired" msgstr "усталый" -#: ../../include/text.php:1273 +#: ../../include/text.php:1270 msgid "perky" msgstr "весёлый" -#: ../../include/text.php:1274 +#: ../../include/text.php:1271 msgid "angry" msgstr "сердитый" -#: ../../include/text.php:1275 +#: ../../include/text.php:1272 msgid "stupefied" msgstr "отупевший" -#: ../../include/text.php:1276 +#: ../../include/text.php:1273 msgid "puzzled" msgstr "недоумевающий" -#: ../../include/text.php:1277 +#: ../../include/text.php:1274 msgid "interested" msgstr "заинтересованный" -#: ../../include/text.php:1278 +#: ../../include/text.php:1275 msgid "bitter" msgstr "едкий" -#: ../../include/text.php:1279 +#: ../../include/text.php:1276 msgid "cheerful" msgstr "бодрый" -#: ../../include/text.php:1280 +#: ../../include/text.php:1277 msgid "alive" msgstr "энергичный" -#: ../../include/text.php:1281 +#: ../../include/text.php:1278 msgid "annoyed" msgstr "раздражённый" -#: ../../include/text.php:1282 +#: ../../include/text.php:1279 msgid "anxious" msgstr "обеспокоенный" -#: ../../include/text.php:1283 +#: ../../include/text.php:1280 msgid "cranky" msgstr "капризный" -#: ../../include/text.php:1284 +#: ../../include/text.php:1281 msgid "disturbed" msgstr "встревоженный" -#: ../../include/text.php:1285 +#: ../../include/text.php:1282 msgid "frustrated" msgstr "разочарованный" -#: ../../include/text.php:1286 +#: ../../include/text.php:1283 msgid "depressed" msgstr "подавленный" -#: ../../include/text.php:1287 +#: ../../include/text.php:1284 msgid "motivated" msgstr "мотивированный" -#: ../../include/text.php:1288 +#: ../../include/text.php:1285 msgid "relaxed" msgstr "расслабленный" -#: ../../include/text.php:1289 +#: ../../include/text.php:1286 msgid "surprised" msgstr "удивленный" -#: ../../include/text.php:1481 +#: ../../include/text.php:1478 msgid "May" msgstr "Май" -#: ../../include/text.php:1539 +#: ../../include/text.php:1536 msgid "Unknown Attachment" msgstr "Неизвестное вложение" -#: ../../include/text.php:1582 +#: ../../include/text.php:1579 msgid "remove category" msgstr "удалить категорию" -#: ../../include/text.php:1659 +#: ../../include/text.php:1656 msgid "remove from file" msgstr "удалить из файла" -#: ../../include/text.php:1842 +#: ../../include/text.php:1840 #: ../../extend/addon/hzaddons/mail/Mod_Mail.php:401 msgid "Download binary/encrypted content" msgstr "Загрузить двоичное / зашифрованное содержимое" -#: ../../include/text.php:1913 -msgid "Poll has ended." -msgstr "Опрос окончен." +#: ../../include/text.php:1914 ../../include/text.php:1923 +#, php-format +msgctxt "noun" +msgid "%d Vote" +msgid_plural "%d Votes" +msgstr[0] "" + +#: ../../include/text.php:1930 +#, php-format +msgctxt "noun" +msgid "%d Vote in total" +msgid_plural "%d Votes in total" +msgstr[0] "" -#: ../../include/text.php:1916 +#: ../../include/text.php:1936 +msgid "Poll has ended" +msgstr "Опрос завершён" + +#: ../../include/text.php:1939 #, php-format -msgid "Poll ends: %s" +msgid "Poll ends in %s" msgstr "Опрос заканчивается %s" -#: ../../include/text.php:2073 +#: ../../include/text.php:2101 msgid "Link to Source" msgstr "Ссылка на источник" -#: ../../include/text.php:2103 +#: ../../include/text.php:2131 msgid "Page layout" msgstr "Шаблон страницы" -#: ../../include/text.php:2103 +#: ../../include/text.php:2131 msgid "You can create your own with the layouts tool" msgstr "Вы можете создать свой собственный с помощью инструмента шаблонов" -#: ../../include/text.php:2114 +#: ../../include/text.php:2142 msgid "HTML" msgstr "" -#: ../../include/text.php:2117 +#: ../../include/text.php:2145 msgid "Comanche Layout" msgstr "Шаблон Comanche" -#: ../../include/text.php:2122 +#: ../../include/text.php:2150 msgid "PHP" msgstr "" -#: ../../include/text.php:2131 +#: ../../include/text.php:2159 msgid "Page content type" msgstr "Тип содержимого страницы" -#: ../../include/text.php:2264 +#: ../../include/text.php:2292 msgid "activity" msgstr "активность" -#: ../../include/text.php:2267 +#: ../../include/text.php:2295 msgid "poll" msgstr "голосование" -#: ../../include/text.php:2380 +#: ../../include/text.php:2408 msgid "a-z, 0-9, -, and _ only" msgstr "Только a-z, 0-9, -, и _" -#: ../../include/text.php:2685 +#: ../../include/text.php:2713 msgid "Design Tools" msgstr "Инструменты дизайна" -#: ../../include/text.php:2691 +#: ../../include/text.php:2719 msgid "Pages" msgstr "Страницы" -#: ../../include/text.php:2703 +#: ../../include/text.php:2731 msgid "Import" msgstr "Импортировать" -#: ../../include/text.php:2704 +#: ../../include/text.php:2732 msgid "Import website..." msgstr "Импорт веб-сайта..." -#: ../../include/text.php:2705 +#: ../../include/text.php:2733 msgid "Select folder to import" msgstr "Выбрать каталог для импорта" -#: ../../include/text.php:2706 +#: ../../include/text.php:2734 msgid "Import from a zipped folder:" msgstr "Импортировать из каталога в zip-архиве:" -#: ../../include/text.php:2707 +#: ../../include/text.php:2735 msgid "Import from cloud files:" msgstr "Импортировать из сетевых файлов:" -#: ../../include/text.php:2708 +#: ../../include/text.php:2736 msgid "/cloud/channel/path/to/folder" msgstr "" -#: ../../include/text.php:2709 +#: ../../include/text.php:2737 msgid "Enter path to website files" msgstr "Введите путь к файлам веб-сайта" -#: ../../include/text.php:2710 +#: ../../include/text.php:2738 msgid "Select folder" msgstr "Выбрать каталог" -#: ../../include/text.php:2711 +#: ../../include/text.php:2739 msgid "Export website..." msgstr "Экспорт веб-сайта..." -#: ../../include/text.php:2712 +#: ../../include/text.php:2740 msgid "Export to a zip file" msgstr "Экспортировать в ZIP файл." -#: ../../include/text.php:2713 +#: ../../include/text.php:2741 msgid "website.zip" msgstr "" -#: ../../include/text.php:2714 +#: ../../include/text.php:2742 msgid "Enter a name for the zip file." msgstr "Введите имя для ZIP файла." -#: ../../include/text.php:2715 +#: ../../include/text.php:2743 msgid "Export to cloud files" msgstr "Эскпортировать в сетевые файлы:" -#: ../../include/text.php:2716 +#: ../../include/text.php:2744 msgid "/path/to/export/folder" msgstr "" -#: ../../include/text.php:2717 +#: ../../include/text.php:2745 msgid "Enter a path to a cloud files destination." msgstr "Введите путь к расположению сетевых файлов." -#: ../../include/text.php:2718 +#: ../../include/text.php:2746 msgid "Specify folder" msgstr "Указать каталог" @@ -12609,7 +12810,7 @@ msgid "" msgstr "Не удалось создать дублирующийся идентификатор канала. Импорт невозможен." #: ../../include/import.php:77 -#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:44 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:43 msgid "Unable to create a unique channel address. Import failed." msgstr "Не удалось создать уникальный адрес канала. Импорт не завершен." @@ -12695,8 +12896,8 @@ msgid "Set shadow depth of photos" msgstr "Глубина теней фотографий" #: ../../view/theme/redbasic/php/config.php:113 -msgid "Set maximum width of content region in pixel" -msgstr "Максимальная ширина содержания региона (в пикселях)" +msgid "Set maximum width of content region in rem" +msgstr "Установить максимальную ширину содержимого в rem" #: ../../view/theme/redbasic/php/config.php:113 msgid "Leave empty for default width" @@ -13073,7 +13274,7 @@ msgstr "Настройки Gravatar обновлены." #: ../../extend/addon/hzaddons/cart/widgets/catalogitem.php:57 #: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:263 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:659 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:660 msgid "Price" msgstr "Цена" @@ -13147,27 +13348,27 @@ msgid "Enable Manual Cart Module" msgstr "Включить модуль ручного управления карточками" #: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:172 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:163 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:164 msgid "New Sku" msgstr "Новый код" #: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:208 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:198 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:199 msgid "Cannot save edits to locked item." msgstr "Невозможно сохранить изменения заблокированной позиции." #: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:252 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:648 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:649 msgid "Changes Locked" msgstr "Изменения заблокированы" #: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:256 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:652 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:653 msgid "Item available for purchase." msgstr "Позиция доступна для приобретения." #: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:266 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:662 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:663 msgid "Photo URL" msgstr "URL изображения" @@ -13189,47 +13390,47 @@ msgstr "Метка" msgid "Instructions" msgstr "Инструкции" -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:64 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:65 msgid "Enable Hubzilla Services Module" msgstr "Включить модуль сервиса Hubzilla" -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:247 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:334 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:248 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:335 msgid "SKU not found." msgstr "Код не найден." -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:300 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:304 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:301 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:305 msgid "Invalid Activation Directive." msgstr "Недействительная директива активации." -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:375 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:379 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:376 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:380 msgid "Invalid Deactivation Directive." msgstr "Недействительная директива деактивации" -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:565 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:566 msgid "Add to this privacy group" msgstr "Добавить в эту группу конфиденциальности" -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:581 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:582 msgid "Set user service class" msgstr "Установить класс обслуживания пользователя" -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:608 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:609 msgid "You must be using a local account to purchase this service." msgstr "Вы должны использовать локальную учётноую запись для покупки этого сервиса." -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:666 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:667 msgid "Add buyer to privacy group" msgstr "Добавить покупателя в группу конфиденциальности" -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:671 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:672 msgid "Add buyer as connection" msgstr "Добавить покупателя как контакт" -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:679 -#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:721 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:680 +#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:722 msgid "Set Service Class" msgstr "Установить класс обслуживания" @@ -14264,11 +14465,11 @@ msgstr "Отслеживаемые теги (через запятую, искл msgid "Diaspora Protocol" msgstr "Протокол Diaspora" -#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:19 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:18 msgid "No username found in import file." msgstr "Имя пользователя не найдено в файле для импорта." -#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:142 +#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:140 msgid "Import completed." msgstr "Импорт завершен." @@ -14294,7 +14495,7 @@ msgstr "Адрес пересылки Diaspora. Например: relay@diaspora msgid "Diaspora relay could not be imported" msgstr "Невозможно импортировать адрес пересылки Diaspora" -#: ../../extend/addon/hzaddons/diaspora/diaspora.php:1015 +#: ../../extend/addon/hzaddons/diaspora/diaspora.php:1027 msgid "No subject" msgstr "Без темы" @@ -14576,12 +14777,12 @@ msgstr "Импорт файлового хранилища Redmatrix" msgid "This will import all your Redmatrix cloud files to this channel." msgstr "Это позволит импортировать все ваши файлы в Redmatrix в этот канал." -#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:30 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:32 msgid "OpenID protocol error. No ID returned." msgstr "Ошибка протокола OpenID. Идентификатор не возвращён." -#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:76 -#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:178 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:78 +#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:179 #, php-format msgid "Welcome %s. Remote authentication successful." msgstr "Добро пожаловать %s. Удаленная аутентификация успешно завершена." diff --git a/view/ru/hstrings.php b/view/ru/hstrings.php index 3e7c70f93..6a17e1be3 100644 --- a/view/ru/hstrings.php +++ b/view/ru/hstrings.php @@ -40,15 +40,21 @@ App::$strings["Please enter your password for verification:"] = "Пожалуй App::$strings["Remove Account"] = "Удалить аккаунт"; App::$strings["Unable to find your hub."] = "Невозможно найти ваш сервер"; App::$strings["Post successful."] = "Успешно опубликовано."; +App::$strings["No content available for year"] = "Содержимое для года недоступно"; App::$strings["Export Channel"] = "Экспорт канала"; -App::$strings["Export your basic channel information to a file. This acts as a backup of your connections, permissions, profile and basic data, which can be used to import your data to a new server hub, but does not contain your content."] = "Экспортировать основную информацию из канала в файл. Служит в качестве резервной копии ваших контактов, основных данных и профиля, однако не включает содержимое. Может быть использовано для импорта ваши данных на новый сервер."; -App::$strings["Export Content"] = "Экспортировать содержимое"; -App::$strings["Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin."] = "Экспортировать информацию из вашего канала и его содержимое в резервную копию в формате JSON которая может быть использована для восстановления или импорта на другом сервере. Сохраняет все ваши контакты, разрешения, данные профиля и публикации за несколько месяцев. Файл может иметь очень большой размер. Пожалуйста, будьте терпеливы и подождите несколько минут пока не начнётся загрузка."; -App::$strings["Export your posts from a given year."] = "Экспортировать ваши публикации за данный год."; -App::$strings["You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range."] = "Вы также можете экспортировать ваши публикации и беседы за определённый месяц или год. Выберите дату в панели местоположения в браузере. Если экспорт будет неудачным (это возможно, например, из-за исчерпания памяти на сервере), повторите попытку, выбрав меньший диапазон дат."; -App::$strings["To select all posts for a given year, such as this year, visit %2\$s"] = "Для выбора всех публикаций заданного года, например текущего, посетите %2\$s"; -App::$strings["To select all posts for a given month, such as January of this year, visit %2\$s"] = "Для выбора всех публикаций заданного месяца, например за январь сего года, посетите %2\$s"; -App::$strings["These content files may be imported or restored by visiting %2\$s on any site containing your channel. For best results please import or restore these in date order (oldest first)."] = "Данные файлы с содержимым могут быть импортированы и восстановлены на любом содержащем ваш канал сайте. Посетите %2\$s. Для лучших результатов пожалуйста производите импорт и восстановление в порядке датировки (старые сначала)."; +App::$strings["Export channel"] = "Экспортировать канал"; +App::$strings["This will export your identity and social graph into a file which can be used to import your channel to a new hub."] = "Экспортировать ваши данные и социальный граф в файл, который можно использовать для импорта вашего канала на новом хабе."; +App::$strings["Export content"] = "Экспортировать содержимое"; +App::$strings["This will export your posts, direct messages, articles and cards per month stored into a zip file per year. Months with no posts will be dismissed."] = "Экспортировать ваши публикации, личные сообщения, статьи и карточки за месяц, хранящиеся в zip-файле за год. Месяцы без сообщений будут отклонены."; +App::$strings["Export wikis"] = "Экспортировать wiki"; +App::$strings["This will export your wikis and wiki pages."] = "Экспортировать ваши wiki и их страницы."; +App::$strings["Export webpages"] = "Экспортировать веб-страницы"; +App::$strings["This will export your webpages and menus."] = "Экспортировать ваши веб-страницы и меню."; +App::$strings["Export channel calendar"] = "Экспортировать календарь канала"; +App::$strings["This will export your channel calendar events and associated items. CalDAV calendars are not included."] = "Экспортировать события календаря вашего канала и связанные элементы, за исключением календарей CalDAV."; +App::$strings["Export chatrooms"] = "Экспортировать комнаты чатов"; +App::$strings["This will export your chatrooms. Chat history is dismissed."] = "Эксортировать ваши комнаты чатов. История не сохраняется."; +App::$strings["This export can be imported or restored by visiting %2\$s on any site containing your channel."] = "Этот файл можно импортировать или восстановить, посетив % 2 $ s на любом сайте, где есть ваш канал."; App::$strings["Away"] = "Нет на месте"; App::$strings["Online"] = "В сети"; App::$strings["Invalid item."] = "Недействительный элемент."; @@ -584,7 +590,10 @@ App::$strings["Homepage"] = "Домашняя страница"; App::$strings["Interests"] = "Интересы"; App::$strings["Location"] = "Место"; App::$strings["Profile updated."] = "Профиль обновлен."; -App::$strings["Hide your connections list from viewers of this profile"] = "Скрывать от просмотра ваш список контактов в этом профиле"; +App::$strings["Hide my connections from viewers of this profile"] = "Скрыть мои контакты от просматривающих этот профиль"; +App::$strings["Publish my default profile in the network directory"] = "Опубликовать мой профиль по умолчанию в каталоге сети"; +App::$strings["Suggest me as a potential contact to new members"] = "Предлагать меня как потенциальный новый контакт для новых участников"; +App::$strings["Reveal my online status"] = "Показать мой статус в сети"; App::$strings["Edit Profile Details"] = "Редактирование профиля"; App::$strings["View this profile"] = "Посмотреть этот профиль"; App::$strings["Edit visibility"] = "Редактировать видимость"; @@ -595,7 +604,7 @@ App::$strings["Create a new profile using these settings"] = "Создать н App::$strings["Clone this profile"] = "Клонировать этот профиль"; App::$strings["Delete this profile"] = "Удалить этот профиль"; App::$strings["Add profile things"] = "Добавить в профиль"; -App::$strings["Personal"] = "Личное"; +App::$strings["Basic"] = "Основной"; App::$strings["Relationship"] = "Отношения"; App::$strings["Miscellaneous"] = "Прочее"; App::$strings["Import profile from file"] = "Импортировать профиль из файла"; @@ -701,11 +710,14 @@ App::$strings["Ignore"] = "Игнорировать"; App::$strings["Recent activity"] = "Последние действия"; App::$strings["Connect"] = "Подключить"; App::$strings["Connect at this location"] = "Подключить в этом месте"; +App::$strings["You have %1$.0f of %2$.0f allowed connections."] = "У вас есть %1$.0f из %2$.0f разрешенных контактов."; App::$strings["Connections"] = "Контакты"; App::$strings["Search"] = "Поиск"; +App::$strings["Contact role"] = "Роль контакта"; App::$strings["Search your connections"] = "Поиск ваших контактов"; -App::$strings["Connections search"] = "Поиск контаков"; +App::$strings["Contact search"] = "Поиск контакта"; App::$strings["Find"] = "Поиск"; +App::$strings["This is a group/forum channel"] = "Это канал группы или форума"; App::$strings["Image uploaded but image cropping failed."] = "Изображение загружено но обрезка не удалась."; App::$strings["Profile Photos"] = "Фотографии профиля"; App::$strings["Image resize failed."] = "Не удалось изменить размер изображения."; @@ -826,14 +838,18 @@ App::$strings["Email verification resent"] = "Сообщение для пров App::$strings["Unable to resend email verification message."] = "Невозможно повторно отправить сообщение для проверки email"; App::$strings["Entry censored"] = "Запись цензурирована"; App::$strings["Entry uncensored"] = "Запись нецензурирована"; -App::$strings["Nothing to import."] = "Ничего импортировать."; -App::$strings["Unable to download data from old server"] = "Невозможно загрузить данные со старого сервера"; -App::$strings["Imported file is empty."] = "Импортированный файл пуст."; -App::$strings["Warning: Database versions differ by %1\$d updates."] = "Предупреждение: Версия базы данных отличается от %1\$d обновления."; -App::$strings["Import completed"] = "Импорт завершён."; +App::$strings["Not a zip file or zip file corrupted."] = "Не zip файл или повреждённый zip файл."; App::$strings["Import Items"] = "Импортировать объекты"; App::$strings["Use this form to import existing posts and content from an export file."] = "Используйте эту форму для импорта существующих публикаций и содержимого из файла."; App::$strings["File to Upload"] = "Файл для загрузки"; +App::$strings["Imported file is empty."] = "Импортированный файл пуст."; +App::$strings["Content import completed"] = "Импорт содержимого завершён"; +App::$strings["Chatroom import completed"] = "Импорт комнат чатов завершён"; +App::$strings["Channel calendar import 1/2 completed"] = "Импорт календаря канала завершён на 1/2"; +App::$strings["Channel calendar import 2/2 completed"] = "Импорт календаря канала завершён на 2/2"; +App::$strings["Menu import completed"] = "Импорт меню завершён"; +App::$strings["Wiki import completed"] = "Импорт wiki завершён"; +App::$strings["Webpages import completed"] = "Импорт веб-страниц завершён"; App::$strings["Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."] = ""; App::$strings["Email resent"] = "Электронная почта повторно отправлена"; App::$strings["Email resend failed"] = "Ошибка повторной отправки электронной почты"; @@ -939,12 +955,20 @@ App::$strings["Copy/paste this URL to link file from a web page"] = "Копир App::$strings["Share this file"] = "Поделиться этим файлом"; App::$strings["Show URL to this file"] = "Показать URL этого файла"; App::$strings["Show in your contacts shared folder"] = "Показать общий каталог в ваших контактах"; +App::$strings["Contact role deleted."] = "Роль контакта удалена."; App::$strings["Permission category name is required."] = "Требуется категория разрешений."; -App::$strings["Permission category saved."] = "Категория разрешения сохранена."; -App::$strings["Use this form to create permission rules for various classes of people or connections."] = "Используйте эту форму для создания правил разрешений для различных групп людей и контактов."; -App::$strings["Permission Categories"] = "Категории разрешений"; -App::$strings["Permission category name"] = "Наименование категории разрешений"; -App::$strings["Some permissions may be inherited from your channel's privacy settings, which have higher priority than individual settings. You can not change those settings here."] = "Некоторые разрешения могут наследовать из настроек приватности ваших каналов которые могут иметь более высокий приоритет чем индивидуальные. Вы не можете менять эти настройки здесь."; +App::$strings["Contact role saved."] = "Роль контакта сохранена."; +App::$strings["Role to assign affected contacts and default role to"] = "Назначить роль выбранных контактов и роль по умолчанию для "; +App::$strings["Role to assign affected contacts to"] = "Назначить роль выбранных контактов для"; +App::$strings["Assign this role to"] = "Назначить эту роль для"; +App::$strings["All my contacts"] = "Все мои контакты"; +App::$strings["Automatically assign this role to new contacts"] = "Автоматически назначать эту роль для новых контактов"; +App::$strings["Contact Roles"] = "Роли контактов"; +App::$strings["Role name"] = "Наименование роли"; +App::$strings["System role - not editable"] = "Системная роль (не редактируется)"; +App::$strings["Deleting"] = "Удаляем"; +App::$strings["Role Permissions"] = "Разрешения роли"; +App::$strings["Some permissions may be inherited from your channel role, which have higher priority than contact role settings."] = "Некоторые разрешения могут быть унаследованы от вашей роли канала, которые имеют более высокий приоритет, чем настройки роли контакта."; App::$strings["Block Name"] = "Название блока"; App::$strings["Edit Block"] = "Редактировать блок"; App::$strings["Post not found."] = "Публикация не найдена"; @@ -978,6 +1002,25 @@ App::$strings["Expiration"] = "Срок действия"; App::$strings["min"] = "мин."; App::$strings["Blocks"] = "Блокировки"; App::$strings["Block Title"] = "Заблокировать заголовок"; +App::$strings["Privacy settings updated."] = "Настройки конфиденциальности обновлены."; +App::$strings["Only me"] = "Только мне"; +App::$strings["Only those you specifically allow"] = "Только персонально разрешённые"; +App::$strings["Approved connections"] = "Одобренные контакты"; +App::$strings["Any connections"] = "Любые контакты"; +App::$strings["Anybody on this website"] = "Любой на этом сайте"; +App::$strings["Anybody in this network"] = "Любой в этой сети"; +App::$strings["Anybody authenticated"] = "Любой аутентифицированный"; +App::$strings["Anybody on the internet"] = "Любой в интернете"; +App::$strings["Advise: set to \"Anybody on the internet\" and use privacy groups to restrict access"] = "Совет: установите значение «Кто угодно в Интернете» и используйте группы конфиденциальности для ограничения доступа."; +App::$strings["Privacy Settings"] = "Настройки конфиденциальности"; +App::$strings["Advanced configuration"] = "Расширенная конфигурация"; +App::$strings["Proceed with caution"] = "Применять с осторожностью"; +App::$strings["Changing advanced configuration settings can impact your, and your contacts channels functionality and security."] = "Изменение дополнительных параметров конфигурации может повлиять на работу и безопасность ваших каналов и контактов."; +App::$strings["Accept the risk and continue"] = "Принять риск и продолжить"; +App::$strings["Automatically approve new contacts"] = "Автоматически одобрять новые контакты"; +App::$strings["Opt-out of search engine indexing"] = "Исключить из индексирования поисковых систем"; +App::$strings["Group actor"] = "Представление группы"; +App::$strings["Allow this channel to act as a forum"] = "Разрешить выступать этому каналу в качестве форума"; App::$strings["Directory Settings"] = "Настройки каталога"; App::$strings["Not valid email."] = "Не действительный адрес email."; App::$strings["Protected email address. Cannot change to that email."] = "Защищенный адрес электронной почты. Нельзя изменить."; @@ -1027,56 +1070,20 @@ App::$strings["Events Settings"] = "Настройки событий"; App::$strings["Personal menu to display in your channel pages"] = "Персональное меню для отображения на странице вашего канала"; App::$strings["Channel Home Settings"] = "Настройки главной страницы канала"; App::$strings["Profiles Settings"] = "Настройки профилей"; -App::$strings["Friends"] = "Друзья"; -App::$strings["Nobody except yourself"] = "Никто кроме вас"; -App::$strings["Only those you specifically allow"] = "Только персонально разрешённые"; -App::$strings["Approved connections"] = "Одобренные контакты"; -App::$strings["Any connections"] = "Любые контакты"; -App::$strings["Anybody on this website"] = "Любой на этом сайте"; -App::$strings["Anybody in this network"] = "Любой в этой сети"; -App::$strings["Anybody authenticated"] = "Любой аутентифицированный"; -App::$strings["Anybody on the internet"] = "Любой в интернете"; -App::$strings["Publish your default profile in the network directory"] = "Публиковать ваш профиль по умолчанию в сетевом каталоге"; -App::$strings["Allow us to suggest you as a potential friend to new members?"] = "Разрешить предлагать вас как потенциального друга для новых пользователей?"; +App::$strings["Please select a channel role"] = "Пожалуйста, выберите роль канала"; App::$strings["Your channel address is"] = "Адрес вашего канала"; App::$strings["Your files/photos are accessible via WebDAV at"] = "Ваши файлы / фотографии доступны через WebDAV по"; -App::$strings["Automatic membership approval"] = "Членство одобрено автоматически"; App::$strings["Channel Settings"] = "Настройки канала"; +App::$strings["Channel role"] = "Роль канала"; App::$strings["Basic Settings"] = "Основные настройки"; -App::$strings["Full Name:"] = "Полное имя:"; -App::$strings["Email Address:"] = "Адрес email:"; -App::$strings["Your Timezone:"] = "Часовой пояс:"; -App::$strings["Default Post Location:"] = "Расположение по умолчанию:"; +App::$strings["Channel timezone:"] = "Часовой пояс канала:"; +App::$strings["Default post location:"] = "Местоположение публикации по умолчанию:"; App::$strings["Geographical location to display on your posts"] = "Показывать географическое положение в ваших публикациях"; -App::$strings["Use Browser Location:"] = "Определять расположение из браузера"; +App::$strings["Use browser location:"] = "Использовать данные о местоположении браузера:"; App::$strings["Adult Content"] = "Содержимое для взрослых"; -App::$strings["This channel frequently or regularly publishes adult content. (Please tag any adult material and/or nudity with #NSFW)"] = "Этот канал часто или регулярно публикует содержимое для взрослых. Пожалуйста, помечайте любой такой материал тегом #NSFW"; -App::$strings["Security and Privacy Settings"] = "Безопасность и настройки приватности"; -App::$strings["Your permissions are already configured. Click to view/adjust"] = "Ваши разрешения уже настроены. Нажмите чтобы просмотреть или изменить"; -App::$strings["Hide my online presence"] = "Скрывать моё присутствие онлайн"; -App::$strings["Prevents displaying in your profile that you are online"] = "Предотвращает отображения статуса \"в сети\" в вашем профиле"; -App::$strings["Simple Privacy Settings:"] = "Простые настройки безопасности:"; -App::$strings["Very Public - extremely permissive (should be used with caution)"] = "Полностью открытый - сверхлиберальный (должен использоваться с осторожностью)"; -App::$strings["Typical - default public, privacy when desired (similar to social network permissions but with improved privacy)"] = "Обычный - открытый по умолчанию, приватность по желанию (как в социальных сетях, но с улучшенными настройками)"; -App::$strings["Private - default private, never open or public"] = "Частный - частный по умочанию, не открытый и не публичный"; -App::$strings["Blocked - default blocked to/from everybody"] = "Закрытый - заблокированный по умолчанию от / для всех"; -App::$strings["Allow others to tag your posts"] = "Разрешить другим отмечать ваши публикации"; -App::$strings["Often used by the community to retro-actively flag inappropriate content"] = "Часто используется сообществом для маркировки неподобающего содержания"; -App::$strings["Channel Permission Limits"] = "Ограничения разрешений канала"; -App::$strings["Expire other channel content after this many days"] = "Храненить содержимое других каналов, дней"; -App::$strings["0 or blank to use the website limit."] = "0 или пусто - использовать настройки сайта."; -App::$strings["This website expires after %d days."] = "Срок хранения содержимого этого сайта истекает через %d дней"; -App::$strings["This website does not expire imported content."] = "Срок хранения импортированного содержимого этого сайта не ограничен."; -App::$strings["The website limit takes precedence if lower than your limit."] = "Ограничение сайта имеет приоритет если ниже вашего значения."; +App::$strings["This channel frequently or regularly publishes adult content"] = "На этом канале часто или регулярно публикуется контент для взрослых"; App::$strings["Maximum Friend Requests/Day:"] = "Запросов в друзья в день:"; App::$strings["May reduce spam activity"] = "Может ограничить спам активность"; -App::$strings["Default Privacy Group"] = "Группа конфиденциальности по умолчанию"; -App::$strings["(click to open/close)"] = "(нажмите чтобы открыть/закрыть)"; -App::$strings["Use my default audience setting for the type of object published"] = "Использовать настройки аудитории по умолчанию для типа опубликованного объекта"; -App::$strings["Channel role and privacy"] = "Роль и конфиденциальность канала"; -App::$strings["Default permissions category"] = "Категория разрешений по умолчанию"; -App::$strings["Maximum private messages per day from unknown people:"] = "Максимально количество сообщений от незнакомых людей, в день:"; -App::$strings["Useful to reduce spamming"] = "Полезно для сокращения количества спама"; App::$strings["Notification Settings"] = "Настройки уведомлений"; App::$strings["By default post a status message when:"] = "По умолчанию публиковать новый статус при:"; App::$strings["accepting a friend request"] = "одобрении запроса в друзья"; @@ -1119,14 +1126,16 @@ App::$strings["Desktop notifications are unavailable because the required browse App::$strings["Grant permission"] = "Предоставить разрешение"; App::$strings["Notify me of events this many days in advance"] = "Уведомлять меня о событиях заранее, дней"; App::$strings["Must be greater than 0"] = "Должно быть больше 0"; -App::$strings["Advanced Account/Page Type Settings"] = "Дополнительные настройки учётной записи / страницы"; -App::$strings["Change the behaviour of this account for special situations"] = "Изменить поведение этого аккаунта в особых ситуациях"; -App::$strings["Miscellaneous Settings"] = "Дополнительные настройки"; App::$strings["Default photo upload folder"] = "Каталог загрузки фотографий по умолчанию"; App::$strings["%Y - current year, %m - current month"] = "%Y - текущий год, %y - текущий месяц"; App::$strings["Default file upload folder"] = "Каталог загрузки файлов по умолчанию"; App::$strings["Remove Channel"] = "Удаление канала"; App::$strings["Remove this channel."] = "Удалить этот канал."; +App::$strings["Expire other channel content after this many days"] = "Храненить содержимое других каналов, дней"; +App::$strings["0 or blank to use the website limit."] = "0 или пусто - использовать настройки сайта."; +App::$strings["This website expires after %d days."] = "Срок хранения содержимого этого сайта истекает через %d дней"; +App::$strings["This website does not expire imported content."] = "Срок хранения импортированного содержимого этого сайта не ограничен."; +App::$strings["The website limit takes precedence if lower than your limit."] = "Ограничение сайта имеет приоритет если ниже вашего значения."; App::$strings["Connections Settings"] = "Настройки контактов"; App::$strings["No feature settings configured"] = "Параметры функций не настроены"; App::$strings["Addon Settings"] = "Настройки расширений"; @@ -1134,6 +1143,62 @@ App::$strings["Please save/submit changes to any panel before opening another."] App::$strings["Poll not found."] = "Опрос не найден"; App::$strings["Invalid response."] = "Неверный ответ."; App::$strings["Response submitted. Updates may not appear instantly."] = "Ответ отправлен. Обновления могут отображаться не сразу."; +App::$strings["Invalid abook_id"] = "Недействительный abook_id"; +App::$strings["Could not locate selected profile."] = "Не удалось обнаружить выбранный профиль."; +App::$strings["is now connected to"] = "теперь подключён к"; +App::$strings["Contact Tools"] = "Инструменты контактов"; +App::$strings["Me"] = "Я"; +App::$strings["Family"] = "Семья"; +App::$strings["Friends"] = "Друзья"; +App::$strings["Acquaintances"] = "Знакомые"; +App::$strings["Approve this contact"] = "Утвердить этот контакт"; +App::$strings["Accept contact to allow communication"] = "Принять контакт, чтобы разрешить общение"; +App::$strings["Please select a role for this contact!"] = "Пожалуйста, выберите роль для этого контакта!"; +App::$strings["This contact is unreachable from this location."] = "Этот контакт недоступен из этого местоположения."; +App::$strings["This contact may be unreachable from other channel locations."] = "Этот контакт может быть недоступен из других мест размещения канала."; +App::$strings["Location independence is not supported by their network."] = "Независимое местоположение не поддерживается их сетью."; +App::$strings["View profile"] = "Просмотреть профиль"; +App::$strings["Select a role for this contact"] = "Выбрать роль для этого контакта"; +App::$strings["Contact roles"] = "Роли контакта"; +App::$strings["Slide to adjust your degree of friendship"] = "Прокрутить для настройки степени дружбы"; +App::$strings["Custom Filter"] = "Настраиваемый фильтр"; +App::$strings["Only import posts with this text"] = "Импортировать публикации только с этим текстом"; +App::$strings["Do not import posts with this text"] = "Не импортировать публикации с этим текстом"; +App::$strings["Approve contact"] = "Утвердить контакт"; +App::$strings["Their"] = "Их"; +App::$strings["My"] = "Мои"; +App::$strings["Contact updated"] = "Контакт обновлён"; +App::$strings["Contact update failed"] = "Обновление контакта не удалось"; +App::$strings["Refresh succeeded"] = "Обновление выполнено"; +App::$strings["Refresh failed - channel is currently unavailable"] = "Ошибка обновления - канал в настоящее время недоступен"; +App::$strings["Block status updated"] = "Статус блокировки обновлён"; +App::$strings["Block failed"] = "Блокировка не удалась"; +App::$strings["Ignore status updated"] = "Статус игнорирования обновлён"; +App::$strings["Ignore failed"] = "Игнорирование не удалось"; +App::$strings["Archive status updated"] = "Статус архивации обновлён"; +App::$strings["Archive failed"] = "Архивация не удалась"; +App::$strings["Hide status updated"] = "Статус скрытия обновлён"; +App::$strings["Hide failed"] = "Скрытие не удалось"; +App::$strings["Contact removed"] = "Контакт удалён"; +App::$strings["Delete failed"] = "Не удалось удалить"; +App::$strings["Refresh Permissions"] = "Обновить разрешения"; +App::$strings["Fetch updated permissions"] = "Получить обновлённые разрешения"; +App::$strings["Refresh Photo"] = "Обновить фотографию"; +App::$strings["Fetch updated photo"] = "Получить обновлённую фотографию"; +App::$strings["Block (or Unblock) all communications with this connection"] = "Блокировать (или разблокировать) связи с этим контактом"; +App::$strings["This connection is blocked!"] = "Этот контакт заблокирован!"; +App::$strings["Unignore"] = "Не игнорировать"; +App::$strings["Ignore (or Unignore) all inbound communications from this connection"] = "Игнорировать (или не игнорировать) все связи для этого контакта"; +App::$strings["This connection is ignored!"] = "Этот контакт игнорируется!"; +App::$strings["Unarchive"] = "Разархивировать"; +App::$strings["Archive"] = "Заархивировать"; +App::$strings["Archive (or Unarchive) this connection - mark channel dead but keep content"] = "Заархивировать (или разархивировать) этот контакт - пометить канал отключённым но сохранить содержимое"; +App::$strings["This connection is archived!"] = "Этот контакт заархивирован!"; +App::$strings["Unhide"] = "Показать"; +App::$strings["Hide"] = "Скрыть"; +App::$strings["Hide or Unhide this connection from your other connections"] = "Скрыть или показать этот контакт от / для остальных"; +App::$strings["This connection is hidden!"] = "Этот контакт скрыт!"; +App::$strings["Delete this connection"] = "Удалить этот контакт"; App::$strings["Location not found."] = "Местоположение не найдено"; App::$strings["Location lookup failed."] = "Поиск местоположения не удался"; App::$strings["Please select another location to become primary before removing the primary location."] = "Пожалуйста, выберите другое местоположение в качестве основного прежде чем удалить предыдущее"; @@ -1152,7 +1217,6 @@ App::$strings["Register is closed"] = "Регистрация закрыта"; App::$strings["Note, the invitation code is valid up to"] = "Обратите внимание: код приглашения действителен до "; App::$strings["Too many recipients for one invitation (max %d)"] = "Слишком много получателей для одного кода приглашения (не более %d)"; App::$strings["No recipients for this invitation"] = "Нет получателей для этого приглашения"; -App::$strings["(%s) : Not a valid email address"] = "(%s) : Недействительный адрес электронной почты"; App::$strings["(%s) : Not a real email address"] = "(%s) : Не настоящий адрес электронной почты"; App::$strings["(%s) : Not allowed email address"] = "(%s) : Не разрешённый адрес электронной почты"; App::$strings["(%s) : email address already in use"] = "(%s) : Адрес электронной почты уже используется"; @@ -1249,8 +1313,6 @@ App::$strings["Examples: \"Bob Jameson\", \"Lisa and her Horses\", \"Soccer\", \ App::$strings["This will be used to create a unique network address (like an email address)."] = "Это будет использовано для создания уникального сетевого адреса (наподобие email)."; App::$strings["Allowed characters are a-z 0-9, - and _"] = "Разрешённые символы a-z 0-9, - и _"; App::$strings["Channel name"] = "Название канала"; -App::$strings["Select a channel permission role compatible with your usage needs and privacy requirements."] = "Выберите разрешения для канала в соответствии с вашими потребностями и требованиями безопасности."; -App::$strings["Read more about channel permission roles"] = "Прочитать больше о разрешениях для каналов"; App::$strings["Create a Channel"] = "Создать канал"; App::$strings["A channel is a unique network identity. It can represent a person (social network profile), a forum (group), a business or celebrity page, a newsfeed, and many other things."] = "Канал это уникальная сетевая идентичность. Он может представлять человека (профиль в социальной сети), форум или группу, бизнес или страницу знаменитости, новостную ленту и многие другие вещи."; App::$strings["or import an existing channel from another location."] = "или импортировать существующий канал из другого места."; @@ -1339,8 +1401,11 @@ App::$strings["Authentication failed."] = "Ошибка аутентификац App::$strings["Enter your channel address (e.g. channel@example.com)"] = "Введите адрес вашего канала (например: channel@example.com)"; App::$strings["Authenticate"] = "Проверка подлинности"; App::$strings["Permissions denied."] = "Доступ запрещен."; +App::$strings["Nothing to import."] = "Ничего импортировать."; +App::$strings["Unable to download data from old server"] = "Невозможно загрузить данные со старого сервера"; App::$strings["Your service plan only allows %d channels."] = "Ваш класс обслуживания разрешает только %d каналов."; App::$strings["No channel. Import failed."] = "Канала нет. Импорт невозможен."; +App::$strings["Automatic content and files import was not possible due to API version incompatiblity. Please import content and files manually!"] = "Автоматический импорт содержимого и файлов был невозможен из-за несовместимости версий API. Пожалуйста, импортируйте контент и файлы вручную!"; App::$strings["You must be logged in to use this feature."] = "Вы должны войти в систему, чтобы использовать эту функцию."; App::$strings["Channel Import"] = "Импортировать канал"; App::$strings["Use this form to import an existing channel from a different server/hub. You may retrieve the channel identity from the old server/hub via the network or provide an export file."] = "Используйте эту форм для импорта существующего канала с другого сервера / хаба. Вы можете получить идентификационные данные канала со старого сервера / хаба через сеть или предоставить файл экспорта."; @@ -1359,6 +1424,8 @@ App::$strings["Privacy group created."] = "Группа конфиденциал App::$strings["Could not create privacy group."] = "Не удалось создать группу конфиденциальности."; App::$strings["Privacy group not found."] = "Группа конфиденциальности не найдена."; App::$strings["Privacy group updated."] = "Группа конфиденциальности обновлена."; +App::$strings["Post to this group by default"] = "Публиковать в этой группе по умолчанию"; +App::$strings["Add new contacts to this group by default"] = "Добавлять новые контакты в эту группу по умолчанию"; App::$strings["Privacy Groups"] = "Группы конфиденциальности"; App::$strings["Add Group"] = "Добавить группу"; App::$strings["Privacy group name"] = "Имя группы конфиденциальности"; @@ -1372,71 +1439,32 @@ App::$strings["Group members"] = "Члены группы"; App::$strings["Not in this group"] = "Не в этой группе"; App::$strings["Click a channel to toggle membership"] = "Нажмите на канал для просмотра членства"; App::$strings["vcard"] = "vCard"; -App::$strings["Could not locate selected profile."] = "Не удалось обнаружить выбранный профиль."; App::$strings["Connection updated."] = "Контакты обновлены."; App::$strings["Failed to update connection record."] = "Не удалось обновить запись контакта."; -App::$strings["is now connected to"] = "теперь подключён к"; App::$strings["Could not access address book record."] = "Не удалось получить доступ к записи адресной книги."; App::$strings["Refresh failed - channel is currently unavailable."] = "Обновление невозможно - в настоящее время канал недоступен."; App::$strings["Unable to set address book parameters."] = "Не удалось получить доступ к параметрам адресной книги."; App::$strings["Connection has been removed."] = "Контакт был удалён."; App::$strings["View Profile"] = "Просмотреть профиль"; App::$strings["View %s's profile"] = "Просмотр %s профиля"; -App::$strings["Refresh Permissions"] = "Обновить разрешения"; -App::$strings["Fetch updated permissions"] = "Получить обновлённые разрешения"; -App::$strings["Refresh Photo"] = "Обновить фотографию"; -App::$strings["Fetch updated photo"] = "Получить обновлённую фотографию"; App::$strings["Recent Activity"] = "Последние действия"; App::$strings["View recent posts and comments"] = "Просмотреть последние публикации и комментарии"; -App::$strings["Block (or Unblock) all communications with this connection"] = "Блокировать (или разблокировать) связи с этим контактом"; -App::$strings["This connection is blocked!"] = "Этот контакт заблокирован!"; -App::$strings["Unignore"] = "Не игнорировать"; -App::$strings["Ignore (or Unignore) all inbound communications from this connection"] = "Игнорировать (или не игнорировать) все связи для этого контакта"; -App::$strings["This connection is ignored!"] = "Этот контакт игнорируется!"; -App::$strings["Unarchive"] = "Разархивировать"; -App::$strings["Archive"] = "Заархивировать"; -App::$strings["Archive (or Unarchive) this connection - mark channel dead but keep content"] = "Заархивировать (или разархивировать) этот контакт - пометить канал отключённым но сохранить содержимое"; -App::$strings["This connection is archived!"] = "Этот контакт заархивирован!"; -App::$strings["Unhide"] = "Показать"; -App::$strings["Hide"] = "Скрыть"; -App::$strings["Hide or Unhide this connection from your other connections"] = "Скрыть или показать этот контакт от / для остальных"; -App::$strings["This connection is hidden!"] = "Этот контакт скрыт!"; -App::$strings["Delete this connection"] = "Удалить этот контакт"; App::$strings["Fetch Vcard"] = "Получить vCard"; App::$strings["Fetch electronic calling card for this connection"] = "Получить электронную телефонную карточку для этого контакта"; -App::$strings["Open Individual Permissions section by default"] = "Открывать раздел \"Индивидуальные разрешения\" по умолчанию"; App::$strings["Affinity"] = "Сходство"; App::$strings["Open Set Affinity section by default"] = "Открыть секцию установления сходства по умолчанию"; -App::$strings["Me"] = "Я"; -App::$strings["Family"] = "Семья"; -App::$strings["Acquaintances"] = "Знакомые"; App::$strings["Filter"] = "Фильтр"; App::$strings["Open Custom Filter section by default"] = "Открывать секцию \"Настраиваемый фильтр\" по умолчанию"; -App::$strings["Approve this connection"] = "Утвердить этот контакт"; -App::$strings["Accept connection to allow communication"] = "Принять контакт чтобы разрешить связь"; App::$strings["Set Affinity"] = "Установить сходство"; App::$strings["Set Profile"] = "Установить профиль"; App::$strings["Set Affinity & Profile"] = "Установить сходство и профиль"; -App::$strings["This connection is unreachable from this location."] = "Этот контакт недоступен для данного местоположения"; -App::$strings["This connection may be unreachable from other channel locations."] = "Этот контакт может быть недоступен из других мест размещения канала"; -App::$strings["Location independence is not supported by their network."] = "Независимое местоположение не поддерживается их сетью."; -App::$strings["This connection is unreachable from this location. Location independence is not supported by their network."] = "Этот контакт недоступен из данного местоположения. Независимое местоположение не поддерживается их сетью."; -App::$strings["Connection: %s"] = "Контакт: %s"; -App::$strings["Connection requests will be approved without your interaction"] = "Запросы контактов будут одобрены без вашего участия"; -App::$strings["This connection's primary address is"] = "Главный адрес это контакта"; +App::$strings["Contact: %s"] = "Контакт: %s"; +App::$strings["Manage contact roles"] = "Управление ролями контактов"; +App::$strings["This contacts's primary address is"] = "Основной адрес этого контакта:"; App::$strings["Available locations:"] = "Доступные расположения:"; -App::$strings["Connection Tools"] = "Инструменты контактов"; -App::$strings["Slide to adjust your degree of friendship"] = "Прокрутить для настройки степени дружбы"; -App::$strings["Rating"] = "Оценка"; -App::$strings["Slide to adjust your rating"] = "Прокрутить для настройки оценки"; -App::$strings["Optionally explain your rating"] = "Объясните свою оценку (не обязательно)"; -App::$strings["Custom Filter"] = "Настраиваемый фильтр"; -App::$strings["Only import posts with this text"] = "Импортировать публикации только с этим текстом"; -App::$strings["Do not import posts with this text"] = "Не импортировать публикации с этим текстом"; -App::$strings["This information is public!"] = "Эта информация общедоступна!"; -App::$strings["Connection Pending Approval"] = "Ожидающие подтверждения контактов"; +App::$strings["Contact Pending Approval"] = "Контакты ожидающие утверждения"; App::$strings["Please choose the profile you would like to display to %s when viewing your profile securely."] = "Пожалуйста, выберите профиль который вы хотит показывать в %s при безопасном просмотре."; -App::$strings["Their Settings"] = "Их настройки"; +App::$strings["Some permissions may be inherited from your channel's privacy settings, which have higher priority than individual settings. You can not change those settings here."] = "Некоторые разрешения могут наследовать из настроек приватности ваших каналов которые могут иметь более высокий приоритет чем индивидуальные. Вы не можете менять эти настройки здесь."; App::$strings["Some permissions may be inherited from your channel's privacy settings, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes."] = "Некоторые разрешения могут быть унаследованы из настроек приватности вашего канала, которые могут иметь более высокий приоритет чем индивидуальные. Вы можете изменить эти настройки, однако они не будут применены до изменения переданных по наследству настроек."; App::$strings["Last update:"] = "Последнее обновление:"; App::$strings["Details"] = "Сведения"; @@ -1563,6 +1591,7 @@ App::$strings["Unable to create element."] = "Невозможно создат App::$strings["Unable to update menu element."] = "Невозможно обновить элемент меню."; App::$strings["Unable to add menu element."] = "Невозможно добавить элемент меню."; App::$strings["Menu Item Permissions"] = "Разрешения на пункт меню"; +App::$strings["(click to open/close)"] = "(нажмите чтобы открыть/закрыть)"; App::$strings["Link Name"] = "Имя ссылки"; App::$strings["Link or Submenu Target"] = "Ссылка или цель подменю"; App::$strings["Enter URL of the link or select a menu name to create a submenu"] = "Введите URL ссылки или выберите имя меню для создания подменю"; @@ -1724,6 +1753,7 @@ App::$strings["Name and Password are required."] = "Требуются имя и App::$strings["Token saved."] = "Токен сохранён."; App::$strings["Use this form to create temporary access identifiers to share things with non-members. These identities may be used in Access Control Lists and visitors may login using these credentials to access private content."] = "Используйте эту форму для создания идентификаторов временного доступа для сторонних пользователей. Эти идентификаторы могут использоваться в списках контроля доступа, и посетители могут использовать эти учетные данные для доступа к частному контенту."; App::$strings["You may also provide dropbox style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:"] = "Вы также можете предоставить доступ в стиле dropbox для друзей и коллег, добавив имя и пароль для входа на любой URL-адрес сайта. Например:"; +App::$strings["Select a role for this token"] = "Выбрать роль для этого токена"; App::$strings["Guest Access Tokens"] = "Токен гостевого доступа"; App::$strings["Login Name"] = "Имя"; App::$strings["Login Password"] = "Пароль"; @@ -1759,13 +1789,6 @@ App::$strings["Create new folder"] = "Создать новую папку"; App::$strings["Upload file"] = "Загрузить файл"; App::$strings["Drop files here to immediately upload"] = "Поместите файлы сюда для немедленной загрузки"; App::$strings["You can select files via the upload button or drop them right here or into an existing folder."] = "Вы можете выбрать файлы с помощью кнопки загрузки или перетащить их сюда или в существующую папку."; -App::$strings["A deleted group with this name was revived. Existing item permissions may apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Удаленная группа с этим названием была восстановлена. Существующие разрешения пункт могут применяться к этой группе и к её будущих участников. Если это не то, чего вы хотели, пожалуйста, создайте другую группу с другим именем."; -App::$strings["Add new connections to this privacy group"] = "Добавить новые контакты в группу конфиденциальности"; -App::$strings["edit"] = "редактировать"; -App::$strings["Edit group"] = "Редактировать группу"; -App::$strings["Add privacy group"] = "Добавить группу конфиденциальности"; -App::$strings["Channels not in any privacy group"] = "Каналы не включены ни в одну группу конфиденциальности"; -App::$strings["add"] = "добавить"; App::$strings["Channel is blocked on this site."] = "Канал блокируется на этом сайте."; App::$strings["Channel location missing."] = "Местоположение канала отсутствует."; App::$strings["Remote channel or protocol unavailable."] = "Удалённый канал или протокол недоступен."; @@ -1787,13 +1810,13 @@ App::$strings["Page update failed."] = "Не удалось обновить с App::$strings["Nothing deleted"] = "Ничего не удалено"; App::$strings["Compare: object not found."] = "Сравнение: объект не найден."; App::$strings["Page updated"] = "Страница обновлена"; -App::$strings["Untitled"] = "Не озаглавлено"; App::$strings["Wiki resource_id required for git commit"] = "Требуется resource_id Wiki для отправки в Git"; App::$strings["__ctx:wiki_history__ Message"] = "Сообщение"; App::$strings["Date"] = "Дата"; App::$strings["Compare"] = "Сравнить"; App::$strings["Different viewers will see this text differently"] = "Различные зрители увидят этот текст по-разному"; -App::$strings["Private Message"] = "Личное сообщение"; +App::$strings["Restricted message"] = "Сообщение с ограниченным доступом"; +App::$strings["Public Policy"] = "Политика общего доступа"; App::$strings["Privacy conflict. Discretion advised."] = "Конфиликт настроек конфиденциальности."; App::$strings["Select"] = "Выбрать"; App::$strings["I will attend"] = "Я буду участвовать"; @@ -1856,7 +1879,6 @@ App::$strings["Safe Mode"] = "Безопасный режим"; App::$strings["Public Forums Only"] = "Только публичные форумы"; App::$strings["This Website Only"] = "Только этот веб-сайт"; App::$strings["Visible to your default audience"] = "Видно вашей аудитории по умолчанию."; -App::$strings["Only me"] = "Только мне"; App::$strings["Public"] = "Общедоступно"; App::$strings["Anybody in the \$Projectname network"] = "Любому в сети \$Projectname"; App::$strings["Any account on %s"] = "Любой аккаунт в %s"; @@ -1909,6 +1931,7 @@ App::$strings["Notes"] = "Записки"; App::$strings["OAuth Apps Manager"] = "Менеджер OAuth"; App::$strings["OAuth2 Apps Manager"] = "Менеджер OAuth2"; App::$strings["PDL Editor"] = "Редактор PDL"; +App::$strings["Permission Categories"] = "Категории разрешений"; App::$strings["My Chatrooms"] = "Мои чаты"; App::$strings["Channel Export"] = "Экспорт канала"; App::$strings["Purchase"] = "Купить"; @@ -1918,11 +1941,12 @@ App::$strings["Remove from app-tray"] = "Удалить из правого ме App::$strings["Pin to navbar"] = "Добавить на панель навигации"; App::$strings["Unpin from navbar"] = "Удалить с панели навигации"; App::$strings["A deleted list with this name was revived. Existing item permissions may apply to this list and any future members. If this is not what you intended, please create another list with a different name."] = "Восстановлен удаленный список с таким именем. Существующие разрешения на элементы могут применяться к этому списку и любым будущим участникам. Если не отвечает вашим намерениям - создайте еще один список с другим именем."; -App::$strings["Add new connections to this access list"] = "Добавить новый контакт в список доступа"; -App::$strings["Lists"] = "Списки"; -App::$strings["Edit list"] = "Редактировать список"; -App::$strings["Create new list"] = "Создать новый список"; -App::$strings["Channels not in any access list"] = "Каналы, не входящие ни в один список доступа"; +App::$strings["Select a privacy group"] = "Выбрать группу конфиденциальности"; +App::$strings["edit"] = "редактировать"; +App::$strings["Edit group"] = "Редактировать группу"; +App::$strings["Create new group"] = "Создать новую группу"; +App::$strings["Channels not in any privacy group"] = "Каналы не включены ни в одну группу конфиденциальности"; +App::$strings["Add"] = "Добавить"; App::$strings["\$Projectname Notification"] = "Оповещение \$Projectname "; App::$strings["\$projectname"] = "\$projectname"; App::$strings["Thank You,"] = "Спасибо,"; @@ -2002,10 +2026,7 @@ App::$strings["2. Intermediate - somewhat comfortable"] = "2. Промежуто App::$strings["3. Advanced - very comfortable"] = "3. Продвинутый - очень удобный"; App::$strings["4. Expert - I can write computer code"] = "4. Эксперт - я умею программировать"; App::$strings["5. Wizard - I probably know more than you do"] = "5. Волшебник - возможно я знаю больше чем ты"; -App::$strings["__ctx:permcat__ default"] = "по умолчанию"; -App::$strings["__ctx:permcat__ follower"] = "поклонник"; -App::$strings["__ctx:permcat__ contributor"] = "участник"; -App::$strings["__ctx:permcat__ publisher"] = "издатель"; +App::$strings["__ctx:permcat__ Default"] = "По умолчанию"; App::$strings["Unable to verify site signature for %s"] = "Невозможно проверить подпись сайта %s"; App::$strings["Unable to verify channel signature"] = "Невозможно проверить подпись канала"; App::$strings["Social Networking"] = "Социальная Сеть"; @@ -2024,6 +2045,9 @@ App::$strings["Special Purpose"] = "Спец. назначение"; App::$strings["Special - Celebrity/Soapbox"] = "Спец. назначение - Знаменитость/Soapbox"; App::$strings["Special - Group Repository"] = "Спец. назначение - Групповой репозиторий"; App::$strings["Custom/Expert Mode"] = "Экспертный режим"; +App::$strings["Personal"] = "Личное"; +App::$strings["Community forum"] = "Форум сообщества"; +App::$strings["Custom"] = "Собственные"; App::$strings["Can view my channel stream and posts"] = "Может просматривать мой поток и сообщения"; App::$strings["Can send me their channel stream and posts"] = "Может присылать мне свои потоки и сообщения"; App::$strings["Can view my default channel profile"] = "Может просматривать мой стандартный профиль канала"; @@ -2038,9 +2062,8 @@ App::$strings["Can post on my channel (wall) page"] = "Может публико App::$strings["Can comment on or like my posts"] = "Может прокомментировать или отмечать как понравившиеся мои публикации"; App::$strings["Can send me direct messages"] = "Может отправлять мне сообщения"; App::$strings["Can like/dislike profiles and profile things"] = "Может комментировать или отмечать как нравится/ненравится мой профиль"; -App::$strings["Can forward direct messages to all my channel connections (forum)"] = "Может пересылать личные сообщения всем своим контактам (форум)"; App::$strings["Can chat with me"] = "Может общаться со мной в чате"; -App::$strings["Can source my public posts in derived channels"] = "Может использовать мои публичные сообщения в клонированных лентах сообщений"; +App::$strings["Can source/mirror my public posts in derived channels"] = "Могу ли я создавать / зеркалировать мои общедоступные сообщения в производных каналах"; App::$strings["Can administer my channel"] = "Может администрировать мой канал"; App::$strings["Select Channel"] = "Выбрать канал"; App::$strings["Read-write"] = "Чтение-запись"; @@ -2158,21 +2181,27 @@ App::$strings["Order unthreaded by date"] = "Сортировка в поряд App::$strings["Stream Order"] = "Упорядочить поток"; App::$strings["Remove term"] = "Удалить выражение"; App::$strings["Saved Searches"] = "Сохранённые поиски"; +App::$strings["add"] = "добавить"; App::$strings["Public and restricted messages"] = "Общедоступные и частные публикации"; App::$strings["Direct messages"] = "Сообщения"; App::$strings["Starred messages"] = "Отмеченные публикации"; App::$strings["No messages"] = "Сообщений нет"; +App::$strings["Read mode"] = "Читать дальше"; +App::$strings["Edit mode"] = "Режим редактирования"; +App::$strings["Editing"] = "Редактируем"; +App::$strings["Saving"] = "Сохраняем"; +App::$strings["Saved"] = "Сохранено"; App::$strings["Private Mail Menu"] = "Меню личной переписки"; App::$strings["Combined View"] = "Комбинированный вид"; App::$strings["Inbox"] = "Входящие"; App::$strings["Outbox"] = "Исходящие"; +App::$strings["Role members"] = "Обладатели роли"; App::$strings["Rating Tools"] = "Инструменты оценки"; App::$strings["Rate Me"] = "Оценить меня"; App::$strings["View Ratings"] = "Просмотр оценок"; App::$strings["Tags"] = "Теги"; App::$strings["__ctx:widget__ Activity"] = "Активность"; App::$strings["App Categories"] = "Категории приложений"; -App::$strings["You have %1$.0f of %2$.0f allowed connections."] = "У вас есть %1$.0f из %2$.0f разрешенных контактов."; App::$strings["Add New Connection"] = "Добавить новый контакт"; App::$strings["Enter channel address"] = "Введите адрес канала"; App::$strings["Examples: bob@example.com, https://example.com/barbara"] = "Пример: ivan@example.com, http://example.com/ivan"; @@ -2185,6 +2214,7 @@ App::$strings["View %s's profile - %s"] = "Просмотр профиля %s - App::$strings["Don't show"] = "Не показывать"; App::$strings["Account settings"] = "Настройки аккаунта"; App::$strings["Channel settings"] = "Настройки канала"; +App::$strings["Privacy settings"] = "Настройки конфиденциальности"; App::$strings["Display settings"] = "Настройки отображения"; App::$strings["Manage locations"] = "Управление местоположением"; App::$strings["l F d, Y \\@ g:i A"] = ""; @@ -2225,6 +2255,7 @@ App::$strings["Male"] = "Мужчина"; App::$strings["Trans"] = "Трансексуал"; App::$strings["Neuter"] = "Среднего рода"; App::$strings["Non-specific"] = "Неспецифический"; +App::$strings["Full Name:"] = "Полное имя:"; App::$strings["Like this channel"] = "нравится этот канал"; App::$strings["j F, Y"] = ""; App::$strings["j F"] = ""; @@ -2323,6 +2354,9 @@ App::$strings["Upload New Photos"] = "Загрузить новые фотогр App::$strings["This is the home page of %s."] = "Это домашняя страница %s."; App::$strings["New window"] = "Новое окно"; App::$strings["Open the selected location in a different window or browser tab"] = "Открыть выбранное местоположение в другом окне или вкладке браузера"; +App::$strings["A deleted group with this name was revived. Existing item permissions may apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Удаленная группа с этим названием была восстановлена. Существующие разрешения пункт могут применяться к этой группе и к её будущих участников. Если это не то, чего вы хотели, пожалуйста, создайте другую группу с другим именем."; +App::$strings["Add new connections to this privacy group"] = "Добавить новые контакты в группу конфиденциальности"; +App::$strings["Manage privacy groups"] = "Управлять группами конфиденциальности"; App::$strings["Delegation session ended."] = "Делегированная сессия завершена."; App::$strings["Logged out."] = "Вышел из системы."; App::$strings["Email validation is incomplete. Please check your email."] = "Проверка email не завершена. Пожалуйста, проверьте вашу почту."; @@ -2331,7 +2365,6 @@ App::$strings["Login failed."] = "Не удалось войти."; App::$strings["Remote authentication"] = "Удаленная аутентификация"; App::$strings["Click to authenticate to your home hub"] = "Нажмите, чтобы аутентифицировать себя на домашнем узле"; App::$strings["Manage your channels"] = "Управление вашими каналами"; -App::$strings["Manage your privacy groups"] = "Управление вашим группами конфиденциальности"; App::$strings["Account/Channel Settings"] = "Настройки аккаунта / канала"; App::$strings["End this session"] = "Закончить эту сессию"; App::$strings["Your profile page"] = "Страницa вашего профиля"; @@ -2369,6 +2402,7 @@ App::$strings["doesn't like %1\$s's %2\$s"] = "Не нравится %1\$s %2\$s App::$strings["%1\$s is now connected with %2\$s"] = "%1\$s теперь в контакте с %2\$s"; App::$strings["%1\$s poked %2\$s"] = "%1\$s ткнул %2\$s"; App::$strings["poked"] = "ткнут"; +App::$strings["Private Message"] = "Личное сообщение"; App::$strings["View %s's profile @ %s"] = "Просмотреть профиль %s @ %s"; App::$strings["Categories:"] = "Категории:"; App::$strings["Filed under:"] = "Хранить под:"; @@ -2464,6 +2498,7 @@ App::$strings["Notice: Permissions have changed but have not yet been submitted. App::$strings["close all"] = "закрыть все"; App::$strings["Nothing new here"] = "Здесь нет ничего нового"; App::$strings["Rate This Channel (this is public)"] = "Оценкa этoго канала (общедоступно)"; +App::$strings["Rating"] = "Оценка"; App::$strings["Describe (optional)"] = "Охарактеризовать (необязательно)"; App::$strings["Please enter a link URL"] = "Пожалуйста, введите URL ссылки"; App::$strings["Unsaved changes. Are you sure you wish to leave this page?"] = "Есть несохраненные изменения. Вы уверены, что хотите покинуть эту страницу?"; @@ -2626,7 +2661,7 @@ App::$strings["Profile Import/Export"] = "Импорт / экспорт проф App::$strings["Save and load profile details across sites/channels"] = "Сохранение и загрузка настроек профиля на всех сайтах / каналах"; App::$strings["Multiple Profiles"] = "Несколько профилей"; App::$strings["Ability to create multiple profiles"] = "Возможность создания нескольких профилей"; -App::$strings["Profile to assign new connections"] = "Назначить профиль для новых контактов"; +App::$strings["Select a profile to assign to this contact"] = "Выберите профиль для этого контакта"; App::$strings["Frequently"] = "Часто"; App::$strings["Hourly"] = "Ежечасно"; App::$strings["Twice daily"] = "Дважды в день"; @@ -2696,6 +2731,7 @@ App::$strings["Visible to approved connections."] = "Видно только о App::$strings["Visible to specific connections."] = "Видно указанным контактам."; App::$strings["Privacy group is empty."] = "Группа конфиденциальности пуста"; App::$strings["Privacy group: %s"] = "Группа конфиденциальности: %s"; +App::$strings["Connection: %s"] = "Контакт: %s"; App::$strings["Connection not found."] = "Контакт не найден."; App::$strings["profile photo"] = "Фотография профиля"; App::$strings["[Edited %s]"] = "[Отредактировано %s]"; @@ -2816,8 +2852,14 @@ App::$strings["Unknown Attachment"] = "Неизвестное вложение"; App::$strings["remove category"] = "удалить категорию"; App::$strings["remove from file"] = "удалить из файла"; App::$strings["Download binary/encrypted content"] = "Загрузить двоичное / зашифрованное содержимое"; -App::$strings["Poll has ended."] = "Опрос окончен."; -App::$strings["Poll ends: %s"] = "Опрос заканчивается %s"; +App::$strings["__ctx:noun__ %d Vote"] = array( + 0 => "", +); +App::$strings["__ctx:noun__ %d Vote in total"] = array( + 0 => "", +); +App::$strings["Poll has ended"] = "Опрос завершён"; +App::$strings["Poll ends in %s"] = "Опрос заканчивается %s"; App::$strings["Link to Source"] = "Ссылка на источник"; App::$strings["Page layout"] = "Шаблон страницы"; App::$strings["You can create your own with the layouts tool"] = "Вы можете создать свой собственный с помощью инструмента шаблонов"; @@ -2883,7 +2925,7 @@ App::$strings["Set font-color for posts and comments"] = "Цвет шрифта App::$strings["Set radius of corners"] = "Радиус скруглений"; App::$strings["Example: 4px"] = "Например: 4px"; App::$strings["Set shadow depth of photos"] = "Глубина теней фотографий"; -App::$strings["Set maximum width of content region in pixel"] = "Максимальная ширина содержания региона (в пикселях)"; +App::$strings["Set maximum width of content region in rem"] = "Установить максимальную ширину содержимого в rem"; App::$strings["Leave empty for default width"] = "Оставьте пустым для ширины по умолчанию"; App::$strings["Set size of conversation author photo"] = "Размер фотографии автора беседы"; App::$strings["Set size of followup author photos"] = "Размер фотографий подписчиков"; -- cgit v1.2.3 From 5aefe0b74f00b199a1f690c1787d26e833d3a2d5 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 18 Dec 2021 19:09:15 +0000 Subject: guest token xchan_network = "token" and remove permission checks since the guest tokens are now added to the abook automatically --- Zotlabs/Lib/Libsync.php | 40 +++++++++++++++++++++++++++++++++++----- include/connections.php | 2 +- include/conversation.php | 2 +- include/permissions.php | 43 ------------------------------------------- include/security.php | 2 +- 5 files changed, 38 insertions(+), 51 deletions(-) diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php index 23573e837..ef10e8046 100644 --- a/Zotlabs/Lib/Libsync.php +++ b/Zotlabs/Lib/Libsync.php @@ -384,19 +384,42 @@ class Libsync { // This relies on the undocumented behaviour that red sites send xchan info with the abook // and import_author_xchan will look them up on all federated networks - if ($abook['abook_xchan'] && $abook['xchan_addr']) { + $found = false; + if ($abook['abook_xchan'] && $abook['xchan_addr'] && (! in_array($abook['xchan_network'], [ 'token', 'unknown' ]))) { $h = Libzot::get_hublocs($abook['abook_xchan']); - if (!$h) { + if ($h) { + $found = true; + } + else { $xhash = import_author_xchan(encode_item_xchan($abook)); - if (!$xhash) { + if ($xhash) { + $found = true; + } + else { logger('Import of ' . $abook['xchan_addr'] . ' failed.'); - continue; } } } + if (!$found && !in_array($abook['xchan_network'], ['zot6', 'activitypub', 'diaspora'])) { + // just import the record. + $xc = []; + foreach ($abook as $k => $v) { + if (strpos($k,'xchan_') === 0) { + $xc[$k] = $v; + } + } + $r = q("select * from xchan where xchan_hash = '%s'", + dbesc($xc['xchan_hash']) + ); + if (! $r) { + xchan_store_lowlevel($xc); + } + } + + foreach ($abook as $k => $v) { - if (in_array($k, $disallowed) || (strpos($k, 'abook') !== 0)) { + if (in_array($k, $disallowed) || (strpos($k, 'abook_') !== 0)) { continue; } if (!in_array($k, $fields)) { @@ -410,6 +433,13 @@ class Libsync { if (array_key_exists('abook_instance', $clean) && $clean['abook_instance'] && strpos($clean['abook_instance'], z_root()) === false) { $clean['abook_not_here'] = 1; + + // guest pass or access token - don't try to probe since it is one-way + // we are relying on the undocumented behaviour that the abook record also contains the xchan + if ($abook['xchan_network'] === 'token') { + $clean['abook_instance'] .= ','; + $clean['abook_instance'] .= z_root(); + } } diff --git a/include/connections.php b/include/connections.php index 98cd4bbb5..a0a9e04a7 100644 --- a/include/connections.php +++ b/include/connections.php @@ -114,7 +114,7 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') { // don't provide a connect button for transient or one-way identities - if(in_array($xchan['xchan_network'],['rss','anon','unknown']) || strpos($xchan['xchan_addr'],'guest:') === 0) { + if(in_array($xchan['xchan_network'],['rss', 'anon', 'unknown', 'token'])) { $connect = false; } diff --git a/include/conversation.php b/include/conversation.php index d12151fcc..bdd27c55f 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1061,7 +1061,7 @@ function thread_author_menu($item, $mode = '') { } else { $url = (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']); - if($local_channel && $url && (! in_array($item['author']['xchan_network'],[ 'rss', 'anon','unknown', 'zot' ]))) { + if($local_channel && $url && (! in_array($item['author']['xchan_network'],[ 'rss', 'anon','unknown', 'zot', 'token']))) { $follow_url = z_root() . '/follow/?f=&url=' . urlencode($url) . '&interactive=0'; } } diff --git a/include/permissions.php b/include/permissions.php index bbd13ed58..c3a9286c0 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -80,23 +80,6 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_ intval($uid), dbesc($observer_xchan) ); - if(! $x) { - // see if they've got a guest access token; these are treated as connections - $y = atoken_abook($uid,$observer_xchan); - if($y) - $x = array($y); - - if(! $x) { - // not in address book and no guest token, see if they've got an xchan - // these *may* have individual (PERMS_SPECIFIC) permissions, but are not connections - $y = q("select xchan_network from xchan where xchan_hash = '%s' limit 1", - dbesc($observer_xchan) - ); - if($y) { - $x = array(pseudo_abook($y[0])); - } - } - } $abook_checked = true; } @@ -309,32 +292,6 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock = if(($x) && in_array($permission,$blocked_anon_perms) && intval($x[0]['abook_ignored'])) return false; - if(! $x) { - // see if they've got a guest access token - $y = atoken_abook($uid,$observer_xchan); - if($y) - $x = array($y); - - if(! $x) { - // not in address book and no guest token, see if they've got an xchan - - $y = q("select xchan_network from xchan where xchan_hash = '%s' limit 1", - dbesc($observer_xchan) - ); - if($y) { - - // This requires an explanation and the effects are subtle. - // The following line creates a fake connection, and this allows - // access tokens to have specific permissions even though they are - // not actual connections. - // The existence of this fake entry must be checked when dealing - // with connection related permissions. - - $x = array(pseudo_abook($y[0])); - } - } - - } $abperms = load_abconfig($uid,$observer_xchan,'my_perms'); } diff --git a/include/security.php b/include/security.php index f02fb8023..7f5f3193f 100644 --- a/include/security.php +++ b/include/security.php @@ -128,7 +128,7 @@ function atoken_xchan($atoken) { 'xchan_hash' => substr($c['channel_hash'], 0, 16) . '.' . $atoken['atoken_guid'], 'xchan_name' => $atoken['atoken_name'], 'xchan_addr' => 'guest:' . $atoken['atoken_name'] . '@' . App::get_hostname(), - 'xchan_network' => 'unknown', + 'xchan_network' => 'token', 'xchan_url' => z_root() . '/guest/' . substr($c['channel_hash'], 0, 16) . '.' . $atoken['atoken_guid'], 'xchan_hidden' => 1, 'xchan_photo_mimetype' => 'image/png', -- cgit v1.2.3 From c36e0805d813121f0587c9f2d585fb32bfd346fa Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Tue, 21 Dec 2021 10:04:51 +0100 Subject: improve pconfig sync at the receiving side --- Zotlabs/Lib/Libsync.php | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php index ef10e8046..36a0a044c 100644 --- a/Zotlabs/Lib/Libsync.php +++ b/Zotlabs/Lib/Libsync.php @@ -230,8 +230,35 @@ class Libsync { if (array_key_exists('config', $arr) && is_array($arr['config']) && count($arr['config'])) { foreach ($arr['config'] as $cat => $k) { - foreach ($arr['config'][$cat] as $k => $v) - set_pconfig($channel['channel_id'], $cat, $k, $v); + $pconfig_updated = []; + + foreach($arr['config'][$cat] as $k => $v) { + if ($cat === 'hz_delpconfig' && strpos($k, 'b64.') === 0) { + $delpconfig = explode(':', unpack_link_id($k)); + + // delete the provided pconfig + del_pconfig($channel['channel_id'], $delpconfig[0], $delpconfig[1], $v); + + // delete the messenger pconfig + del_pconfig($channel['channel_id'], 'hz_delpconfig', $k); + } + + if (strpos($k,'pcfgud:') === 0) { + $realk = substr($k,7); + $pconfig_updated[$realk] = $v; + unset($arr['config'][$cat][$k]); + } + } + + foreach($arr['config'][$cat] as $k => $v) { + if (!isset($pconfig_updated[$k])) { + $pconfig_updated[$k] = NULL; + } + + if ($cat !== 'hz_delpconfig') { + set_pconfig($channel['channel_id'],$cat,$k,$v,$pconfig_updated[$k]); + } + } } } -- cgit v1.2.3 From 1b1fb5d26ac0d0b72d15cb57c337979c1ba15388 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 21 Dec 2021 09:08:36 +0000 Subject: improve pconfig sync at the sending side --- Zotlabs/Lib/PConfig.php | 85 +++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/Zotlabs/Lib/PConfig.php b/Zotlabs/Lib/PConfig.php index 765131f0d..80340f501 100644 --- a/Zotlabs/Lib/PConfig.php +++ b/Zotlabs/Lib/PConfig.php @@ -2,6 +2,8 @@ namespace Zotlabs\Lib; +use App; + /** * @brief Class for handling channel specific configurations. * @@ -32,15 +34,15 @@ class PConfig { if(is_null($uid) || $uid === false) return false; - if(! is_array(\App::$config)) { + if(! is_array(App::$config)) { btlogger('App::$config not an array'); } - if(! array_key_exists($uid, \App::$config)) { - \App::$config[$uid] = array(); + if(! array_key_exists($uid, App::$config)) { + App::$config[$uid] = array(); } - if(! is_array(\App::$config[$uid])) { + if(! is_array(App::$config[$uid])) { btlogger('App::$config[$uid] not an array: ' . $uid); } @@ -52,12 +54,12 @@ class PConfig { foreach($r as $rr) { $k = $rr['k']; $c = $rr['cat']; - if(! array_key_exists($c, \App::$config[$uid])) { - \App::$config[$uid][$c] = array(); - \App::$config[$uid][$c]['config_loaded'] = true; + if(! array_key_exists($c, App::$config[$uid])) { + App::$config[$uid][$c] = array(); + App::$config[$uid][$c]['config_loaded'] = true; } - \App::$config[$uid][$c][$k] = $rr['v']; - \App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated']; + App::$config[$uid][$c][$k] = $rr['v']; + App::$config[$uid][$c]['pcfgud:'.$k] = $rr['updated']; } } } @@ -86,15 +88,15 @@ class PConfig { if(is_null($uid) || $uid === false) return $default; - if(! array_key_exists($uid, \App::$config)) + if(! array_key_exists($uid, App::$config)) self::Load($uid); - if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family]))) + if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family]))) return $default; - return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$uid][$family][$key])) - ? unserialize(\App::$config[$uid][$family][$key]) - : \App::$config[$uid][$family][$key] + return ((! is_array(App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$uid][$family][$key])) + ? unserialize(App::$config[$uid][$family][$key]) + : App::$config[$uid][$family][$key] ); } @@ -133,6 +135,7 @@ class PConfig { $dbvalue = ((is_array($value)) ? serialize($value) : $value); $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); $new = false; + $update = false; $now = datetime_convert(); if (! $updated) { @@ -143,23 +146,22 @@ class PConfig { $updated = datetime_convert('UTC','UTC','-2 seconds'); } - $hash = hash('sha256',$family.':'.$key); + $hash = gen_link_id($family.':'.$key); if (self::Get($uid, 'hz_delpconfig', $hash) !== false) { if (self::Get($uid, 'hz_delpconfig', $hash) > $now) { logger('Refusing to update pconfig with outdated info (Item deleted more recently).', LOGGER_NORMAL, LOG_ERR); return self::Get($uid,$family,$key); } else { - self::Delete($uid,'hz_delpconfig',$hash); + self::Delete($uid, 'hz_delpconfig', $hash); } } if(self::Get($uid, $family, $key) === false) { - if(! array_key_exists($uid, \App::$config)) - \App::$config[$uid] = array(); - if(! array_key_exists($family, \App::$config[$uid])) - \App::$config[$uid][$family] = array(); - + if(! array_key_exists($uid, App::$config)) + App::$config[$uid] = array(); + if(! array_key_exists($family, App::$config[$uid])) + App::$config[$uid][$family] = array(); $ret = q("INSERT INTO pconfig ( uid, cat, k, v, updated ) VALUES ( %d, '%s', '%s', '%s', '%s' ) ", intval($uid), @@ -177,13 +179,14 @@ class PConfig { logger("Error: Insert to pconfig failed.",LOGGER_NORMAL, LOG_ERR); } - \App::$config[$uid][$family]['pcfgud:'.$key] = $updated; + $new = true; + App::$config[$uid][$family]['pcfgud:'.$key] = $updated; } else { - $new = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now); + $update = (App::$config[$uid][$family]['pcfgud:'.$key] < $now); - if ($new) { + if ($update) { // @NOTE There is still a possible race condition under limited circumstances // where a value will be updated by another thread with more current data than @@ -198,7 +201,7 @@ class PConfig { dbesc($key) ); - \App::$config[$uid][$family]['pcfgud:'.$key] = $updated; + App::$config[$uid][$family]['pcfgud:'.$key] = $updated; } else { logger('Refusing to update pconfig with outdated info.', LOGGER_NORMAL, LOG_ERR); @@ -211,16 +214,16 @@ class PConfig { // set in the life of this page. We need this to // synchronise channel clones. - if(! array_key_exists('transient', \App::$config[$uid])) - \App::$config[$uid]['transient'] = array(); - if(! array_key_exists($family, \App::$config[$uid]['transient'])) - \App::$config[$uid]['transient'][$family] = array(); + if(! array_key_exists('transient', App::$config[$uid])) + App::$config[$uid]['transient'] = array(); + if(! array_key_exists($family, App::$config[$uid]['transient'])) + App::$config[$uid]['transient'][$family] = array(); - \App::$config[$uid][$family][$key] = $value; + App::$config[$uid][$family][$key] = $value; - if ($new) { - \App::$config[$uid]['transient'][$family][$key] = $value; - \App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated; + if ($new || $update) { + App::$config[$uid]['transient'][$family][$key] = $value; + App::$config[$uid]['transient'][$family]['pcfgud:'.$key] = $updated; } if($ret) @@ -253,7 +256,7 @@ class PConfig { $updated = ($updated) ? $updated : datetime_convert('UTC','UTC','-2 seconds'); $now = datetime_convert(); - $newer = (\App::$config[$uid][$family]['pcfgud:'.$key] < $now); + $newer = (App::$config[$uid][$family]['pcfgud:'.$key] < $now); if (! $newer) { logger('Refusing to delete pconfig with outdated delete request.', LOGGER_NORMAL, LOG_ERR); @@ -262,12 +265,12 @@ class PConfig { $ret = false; - if (isset(\App::$config[$uid][$family][$key])) { - unset(\App::$config[$uid][$family][$key]); + if (isset(App::$config[$uid][$family][$key])) { + unset(App::$config[$uid][$family][$key]); } - if (isset(\App::$config[$uid][$family]['pcfgud:'.$key])) { - unset(\App::$config[$uid][$family]['pcfgud:'.$key]); + if (isset(App::$config[$uid][$family]['pcfgud:'.$key])) { + unset(App::$config[$uid][$family]['pcfgud:'.$key]); } $ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'", @@ -278,9 +281,9 @@ class PConfig { // Synchronize delete with clones. - if ($family != 'hz_delpconfig') { - $hash = hash('sha256',$family.':'.$key); - set_pconfig($uid,'hz_delpconfig',$hash,$updated); + if ($family !== 'hz_delpconfig') { + $hash = gen_link_id($family.':'.$key); + set_pconfig($uid, 'hz_delpconfig', $hash, $updated); } return $ret; -- cgit v1.2.3 From 8c10fdae5bbdf69998155634d3bae7930dec63d3 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 21 Dec 2021 09:14:48 +0000 Subject: missing label --- Zotlabs/Module/Settings/Channel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php index 214dd505e..82347416d 100644 --- a/Zotlabs/Module/Settings/Channel.php +++ b/Zotlabs/Module/Settings/Channel.php @@ -231,7 +231,7 @@ class Channel { '$timezone' => ['timezone_select', t('Channel timezone:'), $timezone, '', get_timezones()], '$defloc' => ['defloc', t('Default post location:'), $defloc, t('Geographical location to display on your posts')], '$allowloc' => ['allow_location', t('Use browser location:'), ((get_pconfig(local_channel(), 'system', 'use_browser_location')) ? 1 : ''), '', $yes_no], - '$adult' => ['adult', t('Adult Content'), $adult_flag, t('This channel frequently or regularly publishes adult content')], + '$adult' => ['adult', t('Adult Content'), $adult_flag, t('This channel frequently or regularly publishes adult content'), $yes_no], '$maxreq' => ['maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']), t('May reduce spam activity')], '$h_not' => t('Notification Settings'), '$activity_options' => t('By default post a status message when:'), -- cgit v1.2.3 From e14fd920d64793002a51a9abaea736bf59967bec Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 21 Dec 2021 09:19:07 +0000 Subject: version --- boot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot.php b/boot.php index ed2397b43..9bfb8ee88 100644 --- a/boot.php +++ b/boot.php @@ -55,7 +55,7 @@ require_once('include/bbcode.php'); require_once('include/items.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '6.5.11' ); +define ( 'STD_VERSION', '6.5.12' ); define ( 'ZOT_REVISION', '6.0' ); define ( 'DB_UPDATE_VERSION', 1250 ); -- cgit v1.2.3 From f8dfcab0cafdaa816cfaf3767c02641ac4e60ad8 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 21 Dec 2021 09:20:21 +0000 Subject: string change --- Zotlabs/Module/Settings/Channel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php index 82347416d..b192f474d 100644 --- a/Zotlabs/Module/Settings/Channel.php +++ b/Zotlabs/Module/Settings/Channel.php @@ -230,7 +230,7 @@ class Channel { '$h_basic' => t('Basic Settings'), '$timezone' => ['timezone_select', t('Channel timezone:'), $timezone, '', get_timezones()], '$defloc' => ['defloc', t('Default post location:'), $defloc, t('Geographical location to display on your posts')], - '$allowloc' => ['allow_location', t('Use browser location:'), ((get_pconfig(local_channel(), 'system', 'use_browser_location')) ? 1 : ''), '', $yes_no], + '$allowloc' => ['allow_location', t('Use browser location'), ((get_pconfig(local_channel(), 'system', 'use_browser_location')) ? 1 : ''), '', $yes_no], '$adult' => ['adult', t('Adult Content'), $adult_flag, t('This channel frequently or regularly publishes adult content'), $yes_no], '$maxreq' => ['maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']), t('May reduce spam activity')], '$h_not' => t('Notification Settings'), -- cgit v1.2.3 From afa1f1416b3a19d5a4dcccd3a6224963c14b9b5d Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 21 Dec 2021 09:20:53 +0000 Subject: string change --- Zotlabs/Module/Settings/Channel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php index b192f474d..a0da020b7 100644 --- a/Zotlabs/Module/Settings/Channel.php +++ b/Zotlabs/Module/Settings/Channel.php @@ -231,7 +231,7 @@ class Channel { '$timezone' => ['timezone_select', t('Channel timezone:'), $timezone, '', get_timezones()], '$defloc' => ['defloc', t('Default post location:'), $defloc, t('Geographical location to display on your posts')], '$allowloc' => ['allow_location', t('Use browser location'), ((get_pconfig(local_channel(), 'system', 'use_browser_location')) ? 1 : ''), '', $yes_no], - '$adult' => ['adult', t('Adult Content'), $adult_flag, t('This channel frequently or regularly publishes adult content'), $yes_no], + '$adult' => ['adult', t('Adult content'), $adult_flag, t('This channel frequently or regularly publishes adult content'), $yes_no], '$maxreq' => ['maxreq', t('Maximum Friend Requests/Day:'), intval($channel['channel_max_friend_req']), t('May reduce spam activity')], '$h_not' => t('Notification Settings'), '$activity_options' => t('By default post a status message when:'), -- cgit v1.2.3 From 07110cee170970b840bbb479e9271a12b4810137 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 21 Dec 2021 09:58:07 +0000 Subject: add the title to the object --- Zotlabs/Module/Item.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 66629fa2b..41979006e 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -1017,6 +1017,7 @@ class Item extends Controller { $obj['diaspora:guid'] = $uuid; $obj['attributedTo'] = channel_url($channel); $obj['published'] = $created; + $obj['name'] = $title; $datarray['obj'] = $obj; -- cgit v1.2.3 From 27ebeffad41e39dda80159bc27605f5f247174c9 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 22 Dec 2021 09:50:50 +0000 Subject: update_poll() can be called many times in a row for the same item if a multiple poll is being updated. This could result in the queueworker not processing duplicates. We are now adding the source item mid to the notifier call as the third argument (fragment) so that the queueworker will not think they are duplicates. The fragment is also passed to the deliver_hooks call in the notifier --- Zotlabs/Daemon/Notifier.php | 10 ++++++++-- Zotlabs/Lib/Activity.php | 4 +++- Zotlabs/Module/Vote.php | 13 ++++--------- include/text.php | 24 ++++++++++++++++++++++-- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Zotlabs/Daemon/Notifier.php b/Zotlabs/Daemon/Notifier.php index 23bddae8f..76c17545a 100644 --- a/Zotlabs/Daemon/Notifier.php +++ b/Zotlabs/Daemon/Notifier.php @@ -78,6 +78,10 @@ class Notifier { static public $encoded_item = null; static public $channel = null; static public $private = false; + // $fragment can contain additional info to omit de-duplication in the queueworker. + // E.g. if an item is updated many times in a row from different sources (multiple vote updates) the + // update source mid or a timestamp or random string can be added. + static public $fragment = null; static public function run($argc, $argv) { @@ -88,7 +92,6 @@ class Notifier { logger('notifier: invoked: ' . print_r($argv, true), LOGGER_DEBUG); $cmd = $argv[1]; - $item_id = $argv[2]; if (!$item_id) { @@ -103,6 +106,7 @@ class Notifier { self::$encoded_item = null; self::$channel = null; self::$private = false; + self::$fragment = null; $sys = get_sys_channel(); $normal_mode = true; @@ -222,6 +226,8 @@ class Notifier { // Fetch the target item + self::$fragment = $argv[3] ?? ''; + $r = q("SELECT * FROM item WHERE id = %d AND parent != 0", intval($item_id) ); @@ -685,7 +691,7 @@ class Notifier { // This wastes a process if there are no delivery hooks configured, so check this before launching the new process $x = q("select * from hook where hook = 'notifier_normal'"); if ($x) { - Master::Summon(['Deliver_hooks', $target_item['id']]); + Master::Summon(['Deliver_hooks', $target_item['id'], self::$fragment]); } } diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 8e5a4e1a6..ef18040c0 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -2115,6 +2115,7 @@ class Activity { } static function update_poll($item, $post) { + $multi = false; $mid = $post['mid']; $content = $post['title']; @@ -2199,7 +2200,8 @@ class Activity { dbesc(datetime_convert()), intval($item['id']) ); - Master::Summon(['Notifier', 'wall-new', $item['id']]); + + Master::Summon(['Notifier', 'wall-new', $item['id'], $post['mid'] /* trick queueworker de-duplication */ ]); return true; } diff --git a/Zotlabs/Module/Vote.php b/Zotlabs/Module/Vote.php index d67a6f176..4f909d33d 100644 --- a/Zotlabs/Module/Vote.php +++ b/Zotlabs/Module/Vote.php @@ -24,7 +24,7 @@ class Vote extends Controller { $fetch = null; $id = argv(1); $response = $_REQUEST['answer']; - + if ($id) { $fetch = q("select * from item where id = %d limit 1", intval($id) @@ -42,7 +42,7 @@ class Vote extends Controller { } $valid = false; - + if ($obj['oneOf']) { foreach($obj['oneOf'] as $selection) { // logger('selection: ' . $selection); @@ -80,7 +80,6 @@ class Vote extends Controller { $item = []; - $item['aid'] = $channel['channel_account_id']; $item['uid'] = $channel['channel_id']; $item['item_origin'] = 1; @@ -95,11 +94,8 @@ class Vote extends Controller { $item['owner_xchan'] = $fetch[0]['author_xchan']; $item['allow_cid'] = '<' . $fetch[0]['author_xchan'] . '>'; $item['item_private'] = 1; - - $item['obj_type'] = 'Note'; $item['author'] = channelx_by_n($channel['channel_id']); - $item['obj'] = Activity::encode_item($item); // now reset the placeholders @@ -108,17 +104,15 @@ class Vote extends Controller { $item['obj_type'] = 'Answer'; unset($item['author']); - $x = item_store($item); - retain_item($fetch[0]['id']); if($x['success']) { $itemid = $x['item_id']; Master::Summon( [ 'Notifier', 'like', $itemid ] ); } - + $r = q("select * from item where id = %d", intval($itemid) ); @@ -128,6 +122,7 @@ class Vote extends Controller { Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); } } + $ret['success'] = true; $ret['message'] = t('Response submitted. Updates may not appear instantly.'); json_return_and_die($ret); diff --git a/include/text.php b/include/text.php index 84f112802..0522dd3c9 100644 --- a/include/text.php +++ b/include/text.php @@ -1872,6 +1872,13 @@ function format_poll($item,$s,$opts) { $output .= '
    '; } if (array_key_exists('anyOf',$act) && is_array($act['anyOf'])) { + $totalResponses = 0; + foreach ($act['anyOf'] as $poll) { + if (array_path_exists('replies/totalItems',$poll)) { + $totalResponses += intval($poll['replies']['totalItems']); + } + } + foreach ($act['anyOf'] as $poll) { if (array_key_exists('name',$poll) && $poll['name']) { $text = html2plain(purify_html($poll['name']),256); @@ -1882,10 +1889,23 @@ function format_poll($item,$s,$opts) { $total = 0; } if ($activated && $commentable) { - $output .= ' ' . $text . '' . ' (' . $total . ')' . EOL; + //$output .= ' ' . $text . '' . ' (' . $total . ')' . EOL; + + $output .= '  ' . $text . '' . EOL; + $output .= '
    '; + $output .= '
    '; + $output .= '
    '; + $output .= '
    ' . sprintf(tt('%d Vote', '%d Votes', $total, 'noun'), $total) . ' | ' . (($totalResponses) ? intval($total / $totalResponses * 100) . '%' : '0%') . '
    '; + $output .= EOL; } else { - $output .= '[ ] ' . $text . ' (' . $total . ')' . EOL; + //$output .= '[ ] ' . $text . ' (' . $total . ')' . EOL; + $output .= '  ' . $text . '' . EOL; + $output .= '
    '; + $output .= '
    '; + $output .= '
    '; + $output .= '
    ' . sprintf(tt('%d Vote', '%d Votes', $total, 'noun'), $total) . ' | ' . (($totalResponses) ? intval($total / $totalResponses * 100) . '%' : '0%') . '
    '; + $output .= EOL; } } } -- cgit v1.2.3 From 4636e56395e5239ddbf1bbe03355dda73108215a Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 29 Dec 2021 18:45:03 +0000 Subject: minor theme fixes --- view/theme/redbasic/css/style.css | 3 +-- view/theme/redbasic/php/style.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css index 542940404..cea9b8ae5 100644 --- a/view/theme/redbasic/css/style.css +++ b/view/theme/redbasic/css/style.css @@ -397,7 +397,6 @@ footer { .fn { font-weight: bold; font-size: 1rem; - color: #444444; } .vcard-card { @@ -1671,7 +1670,7 @@ dl.bb-dl > dd > li { .onoffswitch.checkbox > div > input:checked + label .onoffswitch-switch { right: 0px; - background-color: #0275d8; + background-color: $link_colour; } diff --git a/view/theme/redbasic/php/style.php b/view/theme/redbasic/php/style.php index 9b8ac455a..9cb835ec6 100644 --- a/view/theme/redbasic/php/style.php +++ b/view/theme/redbasic/php/style.php @@ -75,7 +75,7 @@ if ((!$schema) || ($schema == '---')) { if (! $nav_bg) $nav_bg = '#343a40'; if (! $nav_icon_colour) - $nav_icon_colour = 'rgba(255, 255, 255, 0.5)'; + $nav_icon_colour = 'rgba(255, 255, 255, 0.55)'; if (! $nav_active_icon_colour) $nav_active_icon_colour = 'rgba(255, 255, 255, 0.75)'; if (! $link_colour) -- cgit v1.2.3 From e42703d55793108f456a520dad747db5c9a67518 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 2 Jan 2022 08:49:36 +0000 Subject: lockview: provide guest links for private resources --- Zotlabs/Module/Lockview.php | 86 ++++++++++++++++++++++++++++----------------- view/tpl/navbar_default.tpl | 8 ++--- 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php index 11c781df0..b4ba4caa6 100644 --- a/Zotlabs/Module/Lockview.php +++ b/Zotlabs/Module/Lockview.php @@ -1,6 +1,9 @@ 1) ? argv(1) : 0); if (is_numeric($type)) { $item_id = intval($type); - $type='item'; + $type = 'item'; } else { $item_id = ((argc() > 2) ? intval(argv(2)) : 0); @@ -57,22 +60,33 @@ class Lockview extends \Zotlabs\Web\Controller { killme(); $item = $r[0]; + $uid = null; + $url = ''; - //we have different naming in in menu_item table and chatroom table switch($type) { case 'menu_item': $uid = $item['mitem_channel_id']; break; case 'chatroom': $uid = $item['cr_uid']; + $channel = channelx_by_n($uid); + $url = z_root() . '/chat/' . $channel['channel_address'] . '/' . $item['cr_id']; break; - default: + case 'item': + $uid = $item['uid']; + $url = $item['plink']; + break; + case 'attach': $uid = $item['uid']; + $channel = channelx_by_n($uid); + $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $item['display_path']; + break; + default: break; } if($uid != local_channel()) { - echo ''; + echo ''; killme(); } @@ -93,7 +107,7 @@ class Lockview extends \Zotlabs\Web\Controller { $deny_users = expand_acl($item['deny_cid']); $deny_groups = expand_acl($item['deny_gid']); - $o = ''; + $o = ''; $l = array(); stringify_array_elms($allowed_groups,true); @@ -101,6 +115,7 @@ class Lockview extends \Zotlabs\Web\Controller { stringify_array_elms($deny_groups,true); stringify_array_elms($deny_users,true); + $allowed_xchans = []; $profile_groups = []; if($allowed_groups) { @@ -110,34 +125,39 @@ class Lockview extends \Zotlabs\Web\Controller { } } } + if(count($profile_groups)) { $r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )"); - if($r) - foreach($r as $rr) - $l[] = ''; + if($r) { + foreach($r as $rr) { + $l[] = ''; + } + } } if(count($allowed_groups)) { $r = q("SELECT gname FROM pgrp WHERE hash IN ( " . implode(', ', $allowed_groups) . " )"); - if($r) - foreach($r as $rr) - $l[] = ''; + if($r) { + foreach($r as $rr) { + $gid = AccessList::by_name($uid, $rr['gname']); + $pgrp_members = AccessList::members_xchan($uid, $gid); + $allowed_xchans = array_merge($allowed_xchans, $pgrp_members); + + $l[] = ''; + } + } } + if(count($allowed_users)) { - $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ',$allowed_users) . " )"); - if($r) - foreach($r as $rr) + $r = q("SELECT xchan_name, xchan_hash FROM xchan WHERE xchan_hash IN ( " . implode(', ',$allowed_users) . " )"); + if($r) { + foreach($r as $rr) { + $allowed_xchans[] = $rr['xchan_hash']; $l[] = ''; - if($atokens) { - foreach($atokens as $at) { - if(in_array("'" . $at['xchan_hash'] . "'",$allowed_users)) { - $l[] = ''; - } } } } - $profile_groups = []; if($deny_groups) { foreach($deny_groups as $g) { @@ -146,42 +166,42 @@ class Lockview extends \Zotlabs\Web\Controller { } } } + if(count($profile_groups)) { $r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )"); if($r) foreach($r as $rr) - $l[] = ''; + $l[] = ''; } - - if(count($deny_groups)) { $r = q("SELECT gname FROM pgrp WHERE hash IN ( " . implode(', ', $deny_groups) . " )"); if($r) foreach($r as $rr) - $l[] = ''; + $l[] = ''; } if(count($deny_users)) { $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )"); if($r) foreach($r as $rr) $l[] = ''; + } + + if ($atokens && $allowed_xchans && $url) { + $l[] = ''; + $l[] = ''; - if($atokens) { - foreach($atokens as $at) { - if(in_array("'" . $at['xchan_hash'] . "'",$deny_users)) { - $l[] = ''; - } + $allowed_xchans = array_unique($allowed_xchans); + foreach($atokens as $atoken) { + if(in_array($atoken['xchan_hash'], $allowed_xchans)) { + $l[] = ''; } } - - } echo $o . implode($l); killme(); - } } diff --git a/view/tpl/navbar_default.tpl b/view/tpl/navbar_default.tpl index c8b5ce26c..8d6d5dfd7 100644 --- a/view/tpl/navbar_default.tpl +++ b/view/tpl/navbar_default.tpl @@ -193,7 +193,7 @@
{{if $channel_apps.0}} -