mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 09:01:15 -04:00
Compare commits
200 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53c842c614 | ||
|
|
23ececeb34 | ||
|
|
521c9eb566 | ||
|
|
35877b1382 | ||
|
|
c531287170 | ||
|
|
8e79a81b88 | ||
|
|
b95ceb301f | ||
|
|
76a94495c4 | ||
|
|
b6b2299b4e | ||
|
|
34ddea87d3 | ||
|
|
3d318542cb | ||
|
|
4a8c3cdc61 | ||
|
|
c0b6f2d95f | ||
|
|
9ca7fccab8 | ||
|
|
d91fcfc866 | ||
|
|
29b53f3b9d | ||
|
|
30987095c7 | ||
|
|
43b93de570 | ||
|
|
5b310cf315 | ||
|
|
a1c2a57ea6 | ||
|
|
34bf8f1133 | ||
|
|
c708ec577e | ||
|
|
c185685f2d | ||
|
|
daee5b3477 | ||
|
|
5d0346ee30 | ||
|
|
85ad5355cf | ||
|
|
4c8b84633a | ||
|
|
c0dd4d748d | ||
|
|
c94f25570b | ||
|
|
ffa5e08832 | ||
|
|
63243c8e04 | ||
|
|
21c4ec2de0 | ||
|
|
a8d87af418 | ||
|
|
7b084a065e | ||
|
|
47f6b202e5 | ||
|
|
f588d8379b | ||
|
|
58827e130b | ||
|
|
d702334604 | ||
|
|
b04aa799e3 | ||
|
|
e113f6cb9d | ||
|
|
bc13b7eb72 | ||
|
|
f50b395da6 | ||
|
|
a0e8e40f1c | ||
|
|
cb6055c1b8 | ||
|
|
25424c16e4 | ||
|
|
99dcdee67a | ||
|
|
99928f1aea | ||
|
|
1740ae2104 | ||
|
|
d8372f8433 | ||
|
|
2a15d2c421 | ||
|
|
bacf19688f | ||
|
|
31fbdcf6c5 | ||
|
|
c8818cb7b3 | ||
|
|
eb20789821 | ||
|
|
c90862217e | ||
|
|
df87d6feeb | ||
|
|
6c808abcfc | ||
|
|
f1822bdfab | ||
|
|
c3428acd80 | ||
|
|
d619192b22 | ||
|
|
5bdc713afe | ||
|
|
46eff1c937 | ||
|
|
76e1ea1c02 | ||
|
|
755076a8e5 | ||
|
|
b49f7b8b34 | ||
|
|
c4dd8885e4 | ||
|
|
4c82952b58 | ||
|
|
0da69cb9c7 | ||
|
|
36e244060c | ||
|
|
b13a9f57af | ||
|
|
0aa67ad7f9 | ||
|
|
195a3a6827 | ||
|
|
38ecff1220 | ||
|
|
67e64287af | ||
|
|
b022703b0b | ||
|
|
e8069c0d93 | ||
|
|
7a1c6b64c2 | ||
|
|
8250cb1e8d | ||
|
|
ffe2c4d42b | ||
|
|
f06c970628 | ||
|
|
99bce46b32 | ||
|
|
f711913778 | ||
|
|
a8ac231667 | ||
|
|
f7c8791a6d | ||
|
|
7acc775c91 | ||
|
|
c2e21e837f | ||
|
|
755d0f54f7 | ||
|
|
f62d66ff25 | ||
|
|
406d19f930 | ||
|
|
42b13614eb | ||
|
|
c942bd67fe | ||
|
|
b8dc3d74b6 | ||
|
|
38fb263737 | ||
|
|
b55beed2f9 | ||
|
|
e9278c03c1 | ||
|
|
ae1fe83784 | ||
|
|
717a547c40 | ||
|
|
ec491e87ab | ||
|
|
42e30d0835 | ||
|
|
5b19418e48 | ||
|
|
1bc9a7373f | ||
|
|
23e59b5dcc | ||
|
|
c6b459cf96 | ||
|
|
33254b4cac | ||
|
|
44da40d18d | ||
|
|
c742f25801 | ||
|
|
b153687bf1 | ||
|
|
3318f093da | ||
|
|
d98d56c3b5 | ||
|
|
c3f5f6c7ad | ||
|
|
5f21edcc53 | ||
|
|
cd0731cbb0 | ||
|
|
f392ddec2f | ||
|
|
df71168ab7 | ||
|
|
e93b26bf54 | ||
|
|
a73d4a8cbd | ||
|
|
20ee57801c | ||
|
|
6a270d7f02 | ||
|
|
68639637c9 | ||
|
|
0d1eabbc33 | ||
|
|
dce249f7a9 | ||
|
|
1723d4fbd8 | ||
|
|
c4b09f1a4f | ||
|
|
788c973c13 | ||
|
|
465c5c8cfb | ||
|
|
ee28ba5be1 | ||
|
|
9a22e9cf39 | ||
|
|
2513f605b6 | ||
|
|
3b1ffb2028 | ||
|
|
47c6624e12 | ||
|
|
b6f1b064d3 | ||
|
|
17d89467df | ||
|
|
1282214d48 | ||
|
|
f4bc6ee615 | ||
|
|
f8b8d8c540 | ||
|
|
57ff667438 | ||
|
|
abe3039926 | ||
|
|
82a1117e91 | ||
|
|
b6ff3a4d99 | ||
|
|
f4046efcb2 | ||
|
|
fc1d3831cf | ||
|
|
867deda247 | ||
|
|
f8149face5 | ||
|
|
7e2aecd8bb | ||
|
|
105d121199 | ||
|
|
37d662f2f5 | ||
|
|
5b50454b4d | ||
|
|
b5e4c08fc5 | ||
|
|
db39cd8b7c | ||
|
|
a35f741a35 | ||
|
|
fc02e018cb | ||
|
|
b14a530efb | ||
|
|
f70bc571bd | ||
|
|
8cc64176b4 | ||
|
|
7450ac1a31 | ||
|
|
c72e5e3b66 | ||
|
|
5e811819e2 | ||
|
|
f1c0034a18 | ||
|
|
7342cb81a3 | ||
|
|
b40e858556 | ||
|
|
95a4ed7d6a | ||
|
|
2c2d4b6b95 | ||
|
|
4490eae4fe | ||
|
|
9d59cb0135 | ||
|
|
7d348fe69f | ||
|
|
fa8fb9e73f | ||
|
|
f6093872ec | ||
|
|
e8030e29d9 | ||
|
|
df8bb0596a | ||
|
|
0003e0b8a5 | ||
|
|
e42703d557 | ||
|
|
4636e56395 | ||
|
|
27ebeffad4 | ||
|
|
07110cee17 | ||
|
|
afa1f1416b | ||
|
|
f8dfcab0ca | ||
|
|
e14fd920d6 | ||
|
|
8c10fdae5b | ||
|
|
eee027d9ff | ||
|
|
1b1fb5d26a | ||
|
|
c36e0805d8 | ||
|
|
5c56041185 | ||
|
|
5aefe0b74f | ||
|
|
20e0359efd | ||
|
|
9c790e5a90 | ||
|
|
9c79b5be77 | ||
|
|
2d9a4f4e42 | ||
|
|
565602538c | ||
|
|
78972725ae | ||
|
|
5ab90f7791 | ||
|
|
b90d98fc2b | ||
|
|
eca3ae393b | ||
|
|
2bd69495d2 | ||
|
|
bfd3da43ac | ||
|
|
32a9eaf3b6 | ||
|
|
91cea1f28a | ||
|
|
220ed35f58 | ||
|
|
b1cf5d4e44 | ||
|
|
fe330ec1bb | ||
|
|
2968bf8241 |
78
CHANGELOG
78
CHANGELOG
@@ -1,3 +1,81 @@
|
||||
Hubzilla 7.0.3 (2022-02-10)
|
||||
- Allow to override the charset for the PDO connection string via $db_charset in .htconfig.php
|
||||
|
||||
|
||||
Hubzilla 7.0.2 (2022-02-09)
|
||||
- Update french templates
|
||||
- Add charset to the PDO connection strings
|
||||
- Introduce delete keytype for get_activitystreams_key()
|
||||
- Fix PHP error in Daemon/Externals
|
||||
- Improved actor cache handling
|
||||
- Implement manual fetch of packed local links
|
||||
- Add JSalmon data to the meta field instead of data in Lib/ActivityStreams
|
||||
- Fix some PHP8.1 deprecation warnings
|
||||
- Fix delivery report for likes not found in some cases
|
||||
- Allow zotfinger to recurse through all known hublocs if the one we got does not exist (404) or got removed (410)
|
||||
- Diaspora: improve relaying of comments
|
||||
- Fix regression in mod hcard
|
||||
- Add the LD signature in Daemon/Notifier in case where there is no signed data available
|
||||
- Prevent zot6 packet being saved as AP raw message
|
||||
- Attach iconfig to the activity instead of the activity object
|
||||
|
||||
Addons
|
||||
- Pubcrawl: make sure the sys channel falls through the app installed check
|
||||
- Pubcrawl: improve local delivery of shared inbox items
|
||||
|
||||
|
||||
Hubzilla 7.0.1 (2022-01-28)
|
||||
- Fix removing contacts from privacy groups in the contact edit modal
|
||||
- Fix escape_tags() messing with URLs in actor_store()
|
||||
- Fix pagination in the cards module if a category is selected
|
||||
- Remove unused entries in webfinger
|
||||
- Remove deprecated mail app from apps
|
||||
- Set item_hidden for forum comment announces
|
||||
- Fix relaying of signed messages for activitypub
|
||||
- Fix contact role permissions not re-assigned if the role permission has changed
|
||||
- Fix default channel role not set in rare cases
|
||||
|
||||
Addons
|
||||
- Pubcrawl: fix webfinger not returning the fetched URL
|
||||
- Pubcrawl: improved queue handling for rejected deliveries
|
||||
|
||||
|
||||
Hubzilla 7.0 (2022-01-21)
|
||||
- Provide theme_color and background_color in App::$theme_info for usage in page meta and manifest
|
||||
- PWA improvements according to lighthouse
|
||||
- Refactor mod profile_photo
|
||||
- Remove core legacy mail code
|
||||
- Set session samesite cookie flag
|
||||
- Improve toc bbcode for more flexible usecases
|
||||
- Deprecate include/group in favor of Lib/AccessList
|
||||
- Deprecate AccessList::widget()
|
||||
- Mark forum channel profile images with a small icon in the timelines
|
||||
- Improve privacy groups UI/UX
|
||||
- Do not show connections widget if there are no connections
|
||||
- Remove suggestions widget from various modules
|
||||
- Provide guest access links for private resources in lockview
|
||||
- Improve pconfig syncing
|
||||
- deprecate include/group in favor of Lib/AccessList
|
||||
- Implement background deleting of items in contact_remove()
|
||||
- Refactor guest access tokens for better usability and provide quick access
|
||||
- Refactor permissions handling
|
||||
- Improved poll rendering
|
||||
|
||||
Bugfixes
|
||||
- Fix items not deleted on remote channel purge
|
||||
- Fix plink in post_activity_item()
|
||||
- Fix multiple update_poll() calls dismissed in queueworker
|
||||
- Fix blocked or ignored contacts displayed in connections
|
||||
- Fix polls for forum channels
|
||||
|
||||
Addons:
|
||||
- Legacy mail: remove
|
||||
- Deprecate include/group in favor of Lib/AccessList
|
||||
- Pubcrawl: support pleroma end time for polls
|
||||
- Pubcrawl: slightly adjust the way we check mastodon direct messages
|
||||
- Socialauth: scope support and improvements
|
||||
|
||||
|
||||
Hubzilla 6.4.2 (2021-12-14)
|
||||
- Fix issue in mod sse_bs where returning message id's were assumed to be base64 encoded
|
||||
- Fix announce activity type not registered as response activity
|
||||
|
||||
@@ -89,4 +89,4 @@ class PermissionLimits {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
25
Zotlabs/Daemon/Delxitems.php
Normal file
25
Zotlabs/Daemon/Delxitems.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Daemon;
|
||||
|
||||
require_once('include/connections.php');
|
||||
|
||||
/*
|
||||
* Daemon to remove 'item' resources in the background from a removed connection
|
||||
*/
|
||||
|
||||
class Delxitems {
|
||||
|
||||
static public function run($argc, $argv) {
|
||||
|
||||
cli_startup();
|
||||
|
||||
if($argc != 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove_abook_items($argv[1], $argv[2]);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,9 @@ class Externals {
|
||||
continue;
|
||||
}
|
||||
|
||||
Libzot::fetch_conversation($importer, $message['object']['id']);
|
||||
$obj_id = isset($message['object']['id']) ?? $message['object'];
|
||||
|
||||
Libzot::fetch_conversation($importer, $obj_id);
|
||||
$total++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Zotlabs\Daemon;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\Queue;
|
||||
use Zotlabs\Lib\LDSignatures;
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
require_once('include/conversation.php');
|
||||
@@ -78,6 +79,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 +93,6 @@ class Notifier {
|
||||
logger('notifier: invoked: ' . print_r($argv, true), LOGGER_DEBUG);
|
||||
|
||||
$cmd = $argv[1];
|
||||
|
||||
$item_id = $argv[2];
|
||||
|
||||
if (!$item_id) {
|
||||
@@ -103,6 +107,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 +227,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)
|
||||
);
|
||||
@@ -234,7 +241,7 @@ class Notifier {
|
||||
|
||||
$target_item = $r[0];
|
||||
|
||||
if (in_array($target_item['author']['xchan_network'], ['rss', 'anon'])) {
|
||||
if (in_array($target_item['author']['xchan_network'], ['rss', 'anon', 'token'])) {
|
||||
logger('notifier: target item author is not a fetchable actor', LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
@@ -330,12 +337,14 @@ class Notifier {
|
||||
self::$encoded_item = json_decode($m, true);
|
||||
}
|
||||
else {
|
||||
|
||||
self::$encoded_item = array_merge(['@context' => [
|
||||
ACTIVITYSTREAMS_JSONLD_REV,
|
||||
'https://w3id.org/security/v1',
|
||||
z_root() . ZOT_APSCHEMA_REV
|
||||
]], Activity::encode_activity($target_item)
|
||||
);
|
||||
self::$encoded_item['signature'] = LDSignatures::sign(self::$encoded_item, self::$channel);
|
||||
}
|
||||
|
||||
logger('target_item: ' . print_r($target_item, true), LOGGER_DEBUG);
|
||||
@@ -630,6 +639,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']] : '');
|
||||
@@ -673,7 +694,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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,37 @@
|
||||
<?php
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
|
||||
class AccessList {
|
||||
|
||||
static function add($uid,$name,$public = 0) {
|
||||
|
||||
$ret = false;
|
||||
static function add($uid, $name, $public = 0) {
|
||||
|
||||
$ret = false;
|
||||
$hash = '';
|
||||
if ($uid && $name) {
|
||||
$r = self::byname($uid,$name); // check for dups
|
||||
$r = self::by_name($uid, $name); // check for dups
|
||||
if ($r !== false) {
|
||||
|
||||
// This could be a problem.
|
||||
// This could be a problem.
|
||||
// Let's assume we've just created a list which we once deleted
|
||||
// all the old members are gone, but the list remains so we don't break any security
|
||||
// access lists. What we're doing here is reviving the dead list, but old content which
|
||||
// was restricted to this list may now be seen by the new list members.
|
||||
// was restricted to this list may now be seen by the new list members.
|
||||
|
||||
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
|
||||
intval($r)
|
||||
);
|
||||
if(($z) && $z[0]['deleted']) {
|
||||
if (($z) && $z[0]['deleted']) {
|
||||
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
|
||||
notice( t('A deleted list with this name was revived. Existing item permissions <strong>may</strong> 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 privacy group with this name was revived. Existing item permissions <strong>may</strong> apply to this privacy group and any future members. If this is not what you intended, please create another privacy group 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,46 @@ class AccessList {
|
||||
return false;
|
||||
}
|
||||
|
||||
static function member_remove($uid, $name, $member, $gid = 0) {
|
||||
if (!$gid) {
|
||||
$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 +207,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 +228,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 +244,124 @@ 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'])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return replace_macros(get_markup_template('group_selection.tpl'), [
|
||||
'$label' => t('Add new connections to this access list'),
|
||||
'$groups' => $grps
|
||||
]);
|
||||
|
||||
if ($after) {
|
||||
$grps[] = $after;
|
||||
}
|
||||
|
||||
logger('select: ' . print_r($grps,true), LOGGER_DATA);
|
||||
|
||||
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
|
||||
'$label' => $label,
|
||||
'$form_id' => $form_id,
|
||||
'$groups' => $grps
|
||||
));
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
static function widget($every="connections",$each="lists",$edit = false, $group_id = 0, $cid = '',$mode = 1) {
|
||||
|
||||
$o = '';
|
||||
/* deprecated
|
||||
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('Privacy Groups'),
|
||||
'$edittext' => t('Edit group'),
|
||||
'$createtext' => t('Create new group'),
|
||||
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any privacy group') : ''),
|
||||
'$groups' => $groups,
|
||||
'$add' => t('Add'),
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
static function expand($g) {
|
||||
if (! (is_array($g) && count($g))) {
|
||||
if (!(is_array($g) && count($g))) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -350,8 +371,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 +387,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 +404,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 +413,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 +425,8 @@ class AccessList {
|
||||
foreach ($r as $rv)
|
||||
$ret[] = $rv['gid'];
|
||||
}
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -116,6 +116,11 @@ class Activity {
|
||||
|
||||
$y = json_decode($x['body'], true);
|
||||
logger('returned: ' . json_encode($y, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOGGER_DEBUG);
|
||||
|
||||
if (ActivityStreams::is_an_actor($y['type'])) {
|
||||
XConfig::Set($y['id'], 'system', 'actor_record', $y);
|
||||
}
|
||||
|
||||
return json_decode($x['body'], true);
|
||||
}
|
||||
else {
|
||||
@@ -529,6 +534,7 @@ class Activity {
|
||||
$top_level = (($i['mid'] === $i['parent_mid']) ? true : false);
|
||||
|
||||
if ($public) {
|
||||
|
||||
$ret['to'] = [ACTIVITY_PUBLIC_INBOX];
|
||||
$ret['cc'] = [z_root() . '/followers/' . substr($i['author']['xchan_addr'], 0, strpos($i['author']['xchan_addr'], '@'))];
|
||||
}
|
||||
@@ -660,11 +666,11 @@ class Activity {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function encode_attachment($item) {
|
||||
static function encode_attachment($item, $iconfig = false) {
|
||||
|
||||
$ret = [];
|
||||
|
||||
if (array_key_exists('attach', $item)) {
|
||||
if (!$iconfig && array_key_exists('attach', $item)) {
|
||||
$atts = ((is_array($item['attach'])) ? $item['attach'] : json_decode($item['attach'], true));
|
||||
if ($atts) {
|
||||
foreach ($atts as $att) {
|
||||
@@ -677,7 +683,7 @@ class Activity {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (array_key_exists('iconfig', $item) && is_array($item['iconfig'])) {
|
||||
if ($iconfig && array_key_exists('iconfig', $item) && is_array($item['iconfig'])) {
|
||||
foreach ($item['iconfig'] as $att) {
|
||||
if ($att['sharing']) {
|
||||
$value = ((is_string($att['v']) && preg_match('|^a:[0-9]+:{.*}$|s', $att['v'])) ? unserialize($att['v']) : $att['v']);
|
||||
@@ -886,10 +892,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 +901,10 @@ class Activity {
|
||||
}
|
||||
|
||||
$obj = self::encode_object($i['obj']);
|
||||
if ($obj)
|
||||
|
||||
if ($obj) {
|
||||
$ret['object'] = $obj;
|
||||
}
|
||||
else
|
||||
return [];
|
||||
}
|
||||
@@ -932,6 +936,11 @@ class Activity {
|
||||
$ret['tag'] = $t;
|
||||
}
|
||||
|
||||
$a = self::encode_attachment($i, true);
|
||||
if ($a) {
|
||||
$ret['attachment'] = $a;
|
||||
}
|
||||
|
||||
// addressing madness
|
||||
|
||||
$public = (($i['item_private']) ? false : true);
|
||||
@@ -1042,7 +1051,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 +1098,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) {
|
||||
@@ -1403,7 +1413,7 @@ class Activity {
|
||||
}
|
||||
}
|
||||
|
||||
$x = PermissionRoles::role_perms('social');
|
||||
$x = PermissionRoles::role_perms('personal');
|
||||
$their_perms = Permissions::FilledPerms($x['perms_connect']);
|
||||
|
||||
if ($contact && $contact['abook_id']) {
|
||||
@@ -1520,7 +1530,7 @@ class Activity {
|
||||
'type' => NOTIFY_INTRO,
|
||||
'from_xchan' => $ret['xchan_hash'],
|
||||
'to_xchan' => $channel['channel_hash'],
|
||||
'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'],
|
||||
'link' => z_root() . '/connections#' . $new_connection[0]['abook_id'],
|
||||
]
|
||||
);
|
||||
|
||||
@@ -1554,9 +1564,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']);
|
||||
}
|
||||
|
||||
|
||||
@@ -1704,7 +1714,7 @@ class Activity {
|
||||
|
||||
if ($links) {
|
||||
foreach ($links as $link) {
|
||||
if (array_key_exists('mediaType', $link) && $link['mediaType'] === 'text/html') {
|
||||
if (is_array($link) && array_key_exists('mediaType', $link) && $link['mediaType'] === 'text/html') {
|
||||
$profile = $link['href'];
|
||||
}
|
||||
}
|
||||
@@ -1749,7 +1759,7 @@ class Activity {
|
||||
// update existing xchan record
|
||||
q("update xchan set xchan_name = '%s', xchan_guid = '%s', xchan_pubkey = '%s', xchan_addr = '%s', xchan_network = 'activitypub', xchan_name_date = '%s' where xchan_hash = '%s'",
|
||||
dbesc(escape_tags($name)),
|
||||
dbesc(escape_tags($url)),
|
||||
dbesc($url),
|
||||
dbesc(escape_tags($pubkey)),
|
||||
dbesc(escape_tags($webfinger_addr)),
|
||||
dbescdate(datetime_convert()),
|
||||
@@ -1758,13 +1768,13 @@ class Activity {
|
||||
|
||||
// update existing hubloc record
|
||||
q("update hubloc set hubloc_guid = '%s', hubloc_addr = '%s', hubloc_network = 'activitypub', hubloc_url = '%s', hubloc_host = '%s', hubloc_callback = '%s', hubloc_updated = '%s', hubloc_id_url = '%s' where hubloc_hash = '%s'",
|
||||
dbesc(escape_tags($url)),
|
||||
dbesc($url),
|
||||
dbesc(escape_tags($webfinger_addr)),
|
||||
dbesc(escape_tags($baseurl)),
|
||||
dbesc(escape_tags($hostname)),
|
||||
dbesc(escape_tags($inbox)),
|
||||
dbesc($baseurl),
|
||||
dbesc($hostname),
|
||||
dbesc($inbox),
|
||||
dbescdate(datetime_convert()),
|
||||
dbesc(escape_tags($profile)),
|
||||
dbesc($profile),
|
||||
dbesc($url)
|
||||
);
|
||||
}
|
||||
@@ -1773,8 +1783,8 @@ class Activity {
|
||||
|
||||
xchan_store_lowlevel(
|
||||
[
|
||||
'xchan_hash' => escape_tags($url),
|
||||
'xchan_guid' => escape_tags($url),
|
||||
'xchan_hash' => $url,
|
||||
'xchan_guid' => $url,
|
||||
'xchan_pubkey' => escape_tags($pubkey),
|
||||
'xchan_addr' => $webfinger_addr,
|
||||
'xchan_url' => escape_tags($profile),
|
||||
@@ -1786,16 +1796,16 @@ class Activity {
|
||||
|
||||
hubloc_store_lowlevel(
|
||||
[
|
||||
'hubloc_guid' => escape_tags($url),
|
||||
'hubloc_hash' => escape_tags($url),
|
||||
'hubloc_guid' => $url,
|
||||
'hubloc_hash' => $url,
|
||||
'hubloc_addr' => $webfinger_addr,
|
||||
'hubloc_network' => 'activitypub',
|
||||
'hubloc_url' => escape_tags($baseurl),
|
||||
'hubloc_host' => escape_tags($hostname),
|
||||
'hubloc_callback' => escape_tags($inbox),
|
||||
'hubloc_url' => $baseurl,
|
||||
'hubloc_host' => $hostname,
|
||||
'hubloc_callback' => $inbox,
|
||||
'hubloc_updated' => datetime_convert(),
|
||||
'hubloc_primary' => 1,
|
||||
'hubloc_id_url' => escape_tags($profile)
|
||||
'hubloc_id_url' => $profile
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -2116,6 +2126,7 @@ class Activity {
|
||||
}
|
||||
|
||||
static function update_poll($item, $post) {
|
||||
|
||||
$multi = false;
|
||||
$mid = $post['mid'];
|
||||
$content = $post['title'];
|
||||
@@ -2200,7 +2211,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;
|
||||
}
|
||||
|
||||
@@ -2637,13 +2649,78 @@ class Activity {
|
||||
}
|
||||
}
|
||||
|
||||
set_iconfig($s, 'activitypub', 'recips', $act->raw_recips);
|
||||
$ap_rawmsg = '';
|
||||
$diaspora_rawmsg = '';
|
||||
$raw_arr = [];
|
||||
|
||||
$parent = (($s['parent_mid'] && $s['parent_mid'] === $s['mid']) ? true : false);
|
||||
if ($parent) {
|
||||
$raw_arr = json_decode($act->raw, true);
|
||||
|
||||
// This is a zot6 packet and the raw activitypub or diaspora message json
|
||||
// is possibly available in the attachement.
|
||||
if (array_key_exists('signed', $raw_arr) && is_array($act->data['attachment'])) {
|
||||
foreach($act->data['attachment'] as $a) {
|
||||
if (
|
||||
isset($a['type']) && $a['type'] === 'PropertyValue' &&
|
||||
isset($a['name']) && $a['name'] === 'zot.activitypub.rawmsg' &&
|
||||
isset($a['value'])
|
||||
) {
|
||||
$ap_rawmsg = $a['value'];
|
||||
}
|
||||
if (
|
||||
isset($a['type']) && $a['type'] === 'PropertyValue' &&
|
||||
isset($a['name']) && $a['name'] === 'zot.diaspora.fields' &&
|
||||
isset($a['value'])
|
||||
) {
|
||||
$diaspora_rawmsg = $a['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// old style: can be removed after most hubs are on 7.0.2
|
||||
elseif (array_key_exists('signed', $raw_arr) && is_array($act->obj) && is_array($act->obj['attachment'])) {
|
||||
foreach($act->obj['attachment'] as $a) {
|
||||
if (
|
||||
isset($a['type']) && $a['type'] === 'PropertyValue' &&
|
||||
isset($a['name']) && $a['name'] === 'zot.activitypub.rawmsg' &&
|
||||
isset($a['value'])
|
||||
) {
|
||||
$ap_rawmsg = $a['value'];
|
||||
}
|
||||
|
||||
if (
|
||||
isset($a['type']) && $a['type'] === 'PropertyValue' &&
|
||||
isset($a['name']) && $a['name'] === 'zot.diaspora.fields' &&
|
||||
isset($a['value'])
|
||||
) {
|
||||
$diaspora_rawmsg = $a['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// catch the likes
|
||||
if (!$ap_rawmsg && $response_activity) {
|
||||
$ap_rawmsg = json_encode($act->data, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
// end old style
|
||||
|
||||
if (!$ap_rawmsg && array_key_exists('signed', $raw_arr)) {
|
||||
// zap
|
||||
$ap_rawmsg = json_encode($act->data, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
if ($ap_rawmsg) {
|
||||
set_iconfig($s, 'activitypub', 'rawmsg', $ap_rawmsg, 1);
|
||||
}
|
||||
elseif (!array_key_exists('signed', $raw_arr)) {
|
||||
set_iconfig($s, 'activitypub', 'rawmsg', $act->raw, 1);
|
||||
}
|
||||
|
||||
if ($diaspora_rawmsg) {
|
||||
set_iconfig($s, 'diaspora', 'fields', $diaspora_rawmsg, 1);
|
||||
}
|
||||
|
||||
set_iconfig($s, 'activitypub', 'recips', $act->raw_recips);
|
||||
|
||||
$hookinfo = [
|
||||
'act' => $act,
|
||||
's' => $s
|
||||
@@ -2692,6 +2769,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*/) {
|
||||
@@ -3626,7 +3714,10 @@ class Activity {
|
||||
}
|
||||
|
||||
static function get_cached_actor($id) {
|
||||
$actor = XConfig::Get($id, 'system', 'actor_record');
|
||||
|
||||
// remove any fragments like #main-key since these won't be present in our cached data
|
||||
$cache_url = ((strpos($id, '#')) ? substr($id, 0, strpos($id, '#')) : $id);
|
||||
$actor = XConfig::Get($cache_url, 'system', 'actor_record');
|
||||
|
||||
if ($actor) {
|
||||
return $actor;
|
||||
@@ -3635,7 +3726,7 @@ class Activity {
|
||||
// try other get_cached_actor providers (e.g. diaspora)
|
||||
$hookdata = [
|
||||
'id' => $id,
|
||||
'actor' => false
|
||||
'actor' => null
|
||||
];
|
||||
|
||||
call_hooks('get_cached_actor_provider', $hookdata);
|
||||
|
||||
@@ -11,6 +11,7 @@ class ActivityStreams {
|
||||
|
||||
public $raw = null;
|
||||
public $data = null;
|
||||
public $meta = null;
|
||||
public $valid = false;
|
||||
public $deleted = false;
|
||||
public $id = '';
|
||||
@@ -36,10 +37,14 @@ class ActivityStreams {
|
||||
*/
|
||||
function __construct($string) {
|
||||
|
||||
if(!$string)
|
||||
return;
|
||||
|
||||
$this->raw = $string;
|
||||
|
||||
if (is_array($string)) {
|
||||
$this->data = $string;
|
||||
$this->raw = json_encode($string, JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
else {
|
||||
$this->data = json_decode($string, true);
|
||||
@@ -56,10 +61,10 @@ class ActivityStreams {
|
||||
if ($ret['signer']) {
|
||||
$saved = json_encode($this->data, JSON_UNESCAPED_SLASHES);
|
||||
$this->data = $tmp;
|
||||
$this->data['signer'] = $ret['signer'];
|
||||
$this->data['signed_data'] = $saved;
|
||||
$this->meta['signer'] = $ret['signer'];
|
||||
$this->meta['signed_data'] = $saved;
|
||||
if ($ret['hubloc']) {
|
||||
$this->data['hubloc'] = $ret['hubloc'];
|
||||
$this->meta['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +92,7 @@ class ActivityStreams {
|
||||
|
||||
$this->ldsig = $this->get_compound_property('signature');
|
||||
if ($this->ldsig) {
|
||||
$this->signer = $this->get_compound_property('creator', $this->ldsig);
|
||||
$this->signer = $this->get_actor('creator', $this->ldsig);
|
||||
if ($this->signer && is_array($this->signer) && array_key_exists('publicKey', $this->signer) && is_array($this->signer['publicKey']) && $this->signer['publicKey']['publicKeyPem']) {
|
||||
$this->sigok = LDSignatures::verify($this->data, $this->signer['publicKey']['publicKeyPem']);
|
||||
}
|
||||
@@ -343,10 +348,10 @@ class ActivityStreams {
|
||||
if ($ret['signer']) {
|
||||
$saved = json_encode($x, JSON_UNESCAPED_SLASHES);
|
||||
$x = $tmp;
|
||||
$x['signer'] = $ret['signer'];
|
||||
$x['signed_data'] = $saved;
|
||||
$x['meta']['signer'] = $ret['signer'];
|
||||
$x['meta']['signed_data'] = $saved;
|
||||
if ($ret['hubloc']) {
|
||||
$x['hubloc'] = $ret['hubloc'];
|
||||
$x['meta']['hubloc'] = $ret['hubloc'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,17 +67,15 @@ class Apps {
|
||||
static public function get_base_apps() {
|
||||
$x = get_config('system','base_apps',[
|
||||
'Connections',
|
||||
'Contact Roles',
|
||||
'Network',
|
||||
'Settings',
|
||||
'Files',
|
||||
'Channel Home',
|
||||
'View Profile',
|
||||
'Channel',
|
||||
'Photos',
|
||||
'Calendar',
|
||||
'Directory',
|
||||
'Search',
|
||||
'Help',
|
||||
'Profile Photo',
|
||||
'HQ',
|
||||
'Post'
|
||||
]);
|
||||
@@ -346,7 +344,7 @@ class Apps {
|
||||
'Files' => t('Files'),
|
||||
'Webpages' => t('Webpages'),
|
||||
'Wiki' => t('Wiki'),
|
||||
'Channel Home' => t('Channel Home'),
|
||||
'Channel' => t('Channel'),
|
||||
'View Profile' => t('View Profile'),
|
||||
'Photos' => t('Photos'),
|
||||
'Calendar' => t('Calendar'),
|
||||
@@ -377,10 +375,10 @@ class Apps {
|
||||
'OAuth Apps Manager' => t('OAuth Apps Manager'),
|
||||
'OAuth2 Apps Manager' => t('OAuth2 Apps Manager'),
|
||||
'PDL Editor' => t('PDL Editor'),
|
||||
'Permission Categories' => t('Permission Categories'),
|
||||
'Contact Roles' => t('Contact Roles'),
|
||||
'Public Stream' => t('Public Stream'),
|
||||
'My Chatrooms' => t('My Chatrooms'),
|
||||
'Channel Export' => t('Channel Export'),
|
||||
'Channel Export' => t('Channel Export')
|
||||
);
|
||||
|
||||
if(array_key_exists('name',$arr)) {
|
||||
@@ -428,7 +426,7 @@ class Apps {
|
||||
|
||||
self::translate_system_apps($papp);
|
||||
|
||||
if(trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||
if(isset($papp['plugin']) && trim($papp['plugin']) && (! plugin_is_installed(trim($papp['plugin']))))
|
||||
return '';
|
||||
|
||||
$papp['papp'] = self::papp_encode($papp);
|
||||
|
||||
@@ -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']);
|
||||
}
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -1,405 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
|
||||
class Group {
|
||||
|
||||
static function add($uid,$name,$public = 0) {
|
||||
|
||||
$ret = false;
|
||||
if(x($uid) && x($name)) {
|
||||
$r = self::byname($uid,$name); // check for dups
|
||||
if($r !== false) {
|
||||
|
||||
// This could be a problem.
|
||||
// Let's assume we've just created a group which we once deleted
|
||||
// all the old members are gone, but the group remains so we don't break any security
|
||||
// access lists. What we're doing here is reviving the dead group, but old content which
|
||||
// was restricted to this group may now be seen by the new group members.
|
||||
|
||||
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
|
||||
intval($r)
|
||||
);
|
||||
if(($z) && $z[0]['deleted']) {
|
||||
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
|
||||
notice( t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> 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;
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,19 +411,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 +460,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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'])) {
|
||||
@@ -1217,7 +1218,7 @@ class Libzot {
|
||||
|
||||
if (in_array($env['type'], ['activity', 'response'])) {
|
||||
|
||||
if(!isset($AS->actor['id'])) {
|
||||
if(empty($AS->actor['id'])) {
|
||||
logger('No actor id!');
|
||||
return;
|
||||
}
|
||||
@@ -1295,9 +1296,8 @@ class Libzot {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($AS->data['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->data['signed_data'], false);
|
||||
if ($AS->meta['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->meta['signed_data'], false);
|
||||
}
|
||||
|
||||
logger('Activity received: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG);
|
||||
@@ -1592,6 +1592,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']),
|
||||
@@ -1925,6 +1926,7 @@ class Libzot {
|
||||
dbesc($a['signature']['signer'])
|
||||
);
|
||||
|
||||
|
||||
foreach ($items as $activity) {
|
||||
|
||||
$AS = new ActivityStreams($activity);
|
||||
@@ -1986,9 +1988,9 @@ class Libzot {
|
||||
$arr['item_verified'] = true;
|
||||
}
|
||||
|
||||
if ($AS->data['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->data['signed_data'], false);
|
||||
$j = json_decode($AS->data['signed_data'], true);
|
||||
if ($AS->meta['signed_data']) {
|
||||
IConfig::Set($arr, 'activitypub', 'signed_data', $AS->meta['signed_data'], false);
|
||||
$j = json_decode($AS->meta['signed_data'], true);
|
||||
if ($j) {
|
||||
IConfig::Set($arr, 'activitypub', 'rawmsg', json_encode(JSalmon::unpack($j['data'])), true);
|
||||
}
|
||||
@@ -2480,14 +2482,14 @@ class Libzot {
|
||||
$access_policy = ACCESS_PRIVATE;
|
||||
}
|
||||
|
||||
$directory_url = htmlspecialchars($arr['directory_url'], ENT_COMPAT, 'UTF-8', false);
|
||||
$url = htmlspecialchars(strtolower($arr['url']), ENT_COMPAT, 'UTF-8', false);
|
||||
$sellpage = htmlspecialchars($arr['sellpage'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_location = htmlspecialchars($arr['location'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_realm = htmlspecialchars($arr['realm'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_project = htmlspecialchars($arr['project'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_crypto = ((array_key_exists('encryption', $arr) && is_array($arr['encryption'])) ? htmlspecialchars(implode(',', $arr['encryption']), ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_version = ((array_key_exists('version', $arr)) ? htmlspecialchars($arr['version'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$directory_url = htmlspecialchars((string)$arr['directory_url'], ENT_COMPAT, 'UTF-8', false);
|
||||
$url = htmlspecialchars((string)strtolower($arr['url']), ENT_COMPAT, 'UTF-8', false);
|
||||
$sellpage = htmlspecialchars((string)$arr['sellpage'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_location = htmlspecialchars((string)$arr['location'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_realm = htmlspecialchars((string)$arr['realm'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_project = htmlspecialchars((string)$arr['project'], ENT_COMPAT, 'UTF-8', false);
|
||||
$site_crypto = ((array_key_exists('encryption', $arr) && is_array($arr['encryption'])) ? htmlspecialchars((string)implode(',', $arr['encryption']), ENT_COMPAT, 'UTF-8', false) : '');
|
||||
$site_version = ((array_key_exists('version', $arr)) ? htmlspecialchars((string)$arr['version'], ENT_COMPAT, 'UTF-8', false) : '');
|
||||
|
||||
// You can have one and only one primary directory per realm.
|
||||
// Downgrade any others claiming to be primary. As they have
|
||||
@@ -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'));
|
||||
|
||||
@@ -3189,7 +3172,7 @@ class Libzot {
|
||||
}
|
||||
|
||||
static function update_cached_hubloc($hubloc) {
|
||||
if ($hubloc['hubloc_updated'] > datetime_convert('UTC','UTC','now - 1 week') || $hubloc['hubloc_url'] === z_root()) {
|
||||
if ($hubloc['hubloc_updated'] > datetime_convert('UTC','UTC','now - 3 days') || $hubloc['hubloc_url'] === z_root()) {
|
||||
return;
|
||||
}
|
||||
self::refresh( [ 'hubloc_id_url' => $hubloc['hubloc_id_url'] ] );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Zotlabs\Lib;
|
||||
|
||||
use Zotlabs\Access\PermissionRoles;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Daemon\Master;
|
||||
|
||||
/**
|
||||
* @brief Permission Categories. Permission rules for various classes of connections.
|
||||
@@ -38,33 +39,33 @@ class Permcat {
|
||||
|
||||
// first check role perms for a perms_connect setting
|
||||
|
||||
$role = get_pconfig($channel_id,'system','permissions_role');
|
||||
if($role) {
|
||||
$role = get_pconfig($channel_id, 'system', 'permissions_role');
|
||||
if ($role) {
|
||||
$x = PermissionRoles::role_perms($role);
|
||||
if($x['perms_connect']) {
|
||||
if ($x['perms_connect']) {
|
||||
$perms = Permissions::FilledPerms($x['perms_connect']);
|
||||
}
|
||||
}
|
||||
|
||||
// if no role perms it may be a custom role, see if there any autoperms
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$perms = Permissions::FilledAutoPerms($channel_id);
|
||||
}
|
||||
|
||||
// if no autoperms it may be a custom role with manual perms
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$r = q("select channel_hash from channel where channel_id = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
if ($r) {
|
||||
$x = q("select * from abconfig where chan = %d and xchan = '%s' and cat = 'my_perms'",
|
||||
intval($channel_id),
|
||||
dbesc($r[0]['channel_hash'])
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
if ($x) {
|
||||
foreach ($x as $xv) {
|
||||
$perms[$xv['k']] = intval($xv['v']);
|
||||
}
|
||||
}
|
||||
@@ -73,25 +74,27 @@ class Permcat {
|
||||
|
||||
// nothing was found - create a filled permission array where all permissions are 0
|
||||
|
||||
if(! $perms) {
|
||||
if (!$perms) {
|
||||
$perms = Permissions::FilledPerms([]);
|
||||
}
|
||||
|
||||
$this->permcats[] = [
|
||||
'name' => 'default',
|
||||
'localname' => t('default','permcat'),
|
||||
'localname' => t('Default', 'permcat'),
|
||||
'perms' => Permissions::Operms($perms),
|
||||
'raw_perms' => $perms,
|
||||
'system' => 1
|
||||
];
|
||||
|
||||
|
||||
$p = $this->load_permcats($channel_id);
|
||||
if($p) {
|
||||
for($x = 0; $x < count($p); $x++) {
|
||||
if ($p) {
|
||||
for ($x = 0; $x < count($p); $x++) {
|
||||
$this->permcats[] = [
|
||||
'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])
|
||||
];
|
||||
}
|
||||
@@ -116,9 +119,9 @@ class Permcat {
|
||||
* * \e bool \b error if $name not found in permcats true
|
||||
*/
|
||||
public function fetch($name) {
|
||||
if($name && $this->permcats) {
|
||||
foreach($this->permcats as $permcat) {
|
||||
if(strcasecmp($permcat['name'], $name) === 0) {
|
||||
if ($name && $this->permcats) {
|
||||
foreach ($this->permcats as $permcat) {
|
||||
if (strcasecmp($permcat['name'], $name) === 0) {
|
||||
return $permcat;
|
||||
}
|
||||
}
|
||||
@@ -128,31 +131,28 @@ 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','view_wiki',
|
||||
'post_wall','post_comments','write_wiki','post_like','tag_deliver','chat' ], 1
|
||||
],
|
||||
[ 'publisher', t('publisher','permcat'),
|
||||
[ '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_like','tag_deliver',
|
||||
'chat', 'republish' ], 1
|
||||
]
|
||||
'write_storage','post_wall','write_pages','write_wiki','post_comments', 'post_mail', 'post_like',
|
||||
'chat' ], 1
|
||||
],
|
||||
[ 'muted', t('Muted','permcat'),
|
||||
[ 'view_stream','view_profile','view_contacts','view_storage','view_pages','view_wiki',
|
||||
'post_comments','write_wiki','post_like' ], 1
|
||||
],
|
||||
];
|
||||
|
||||
if($uid) {
|
||||
*/
|
||||
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']);
|
||||
$permcats[] = [ $xv['k'], $xv['k'], $value, 0 ];
|
||||
|
||||
if ($x) {
|
||||
foreach ($x as $xv) {
|
||||
$value = ((preg_match('|^a:[0-9]+:{.*}$|s', $xv['v'])) ? unserialize($xv['v']) : $xv['v']);
|
||||
$permcats[] = [$xv['k'], $xv['k'], $value, 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,11 +167,11 @@ class Permcat {
|
||||
}
|
||||
|
||||
static public function find_permcat($arr, $name) {
|
||||
if((! $arr) || (! $name))
|
||||
if ((!$arr) || (!$name))
|
||||
return false;
|
||||
|
||||
foreach($arr as $p)
|
||||
if($p['name'] == $name)
|
||||
foreach ($arr as $p)
|
||||
if ($p['name'] == $name)
|
||||
return $p['value'];
|
||||
}
|
||||
|
||||
@@ -183,4 +183,105 @@ class Permcat {
|
||||
PConfig::Delete($channel_id, 'permcat', $name);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief assign a contact role to contacts
|
||||
*
|
||||
* @param array $channel
|
||||
* @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['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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Access\AccessList;
|
||||
|
||||
require_once('include/text.php');
|
||||
|
||||
@@ -58,6 +60,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 +103,25 @@ 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']);
|
||||
|
||||
if ($locktype === 2) {
|
||||
$lock = t('Direct message');
|
||||
}
|
||||
|
||||
// 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 +129,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');
|
||||
@@ -384,6 +413,12 @@ class ThreadItem {
|
||||
$pinned_items = ($allowed_type ? get_pconfig($item['uid'], 'pinned', $item['item_type'], []) : []);
|
||||
$pinned = ((!empty($pinned_items) && in_array($midb64, $pinned_items)) ? true : false);
|
||||
|
||||
$contact = [];
|
||||
|
||||
if(App::$contacts && array_key_exists($item['author_xchan'], App::$contacts)) {
|
||||
$contact = App::$contacts[$item['author_xchan']];
|
||||
}
|
||||
|
||||
$tmp_item = array(
|
||||
'template' => $this->get_template(),
|
||||
'mode' => $mode,
|
||||
@@ -401,6 +436,7 @@ class ThreadItem {
|
||||
'mids' => $json_mids,
|
||||
'parent' => $item['parent'],
|
||||
'author_id' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
|
||||
'author_is_group_actor' => (($item['author']['xchan_pubforum']) ? t('Forum') : ''),
|
||||
'isevent' => $isevent,
|
||||
'attend' => $attend,
|
||||
'consensus' => $consensus,
|
||||
@@ -503,7 +539,9 @@ class ThreadItem {
|
||||
'wait' => t('Please wait'),
|
||||
'thread_level' => $thread_level,
|
||||
'settings' => $settings,
|
||||
'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? gen_link_id($item['thr_parent']) : '')
|
||||
'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? gen_link_id($item['thr_parent']) : ''),
|
||||
'contact_id' => (($contact) ? $contact['abook_id'] : '')
|
||||
|
||||
);
|
||||
|
||||
$arr = array('item' => $item, 'output' => $tmp_item);
|
||||
|
||||
@@ -87,4 +87,4 @@ class ZotURL {
|
||||
return ids_to_array($r,'hubloc_url');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use Zotlabs\Web\HTTPSig;
|
||||
|
||||
class Zotfinger {
|
||||
|
||||
static function exec($resource,$channel = null, $verify = true) {
|
||||
static function exec($resource, $channel = null, $verify = true, $recurse = true) {
|
||||
|
||||
if(! $resource) {
|
||||
return false;
|
||||
@@ -39,6 +39,30 @@ class Zotfinger {
|
||||
|
||||
logger('fetch: ' . print_r($x,true));
|
||||
|
||||
if (in_array(intval($x['return_code']), [ 404, 410 ]) && $recurse) {
|
||||
|
||||
// The resource has been deleted or doesn't exist at this location.
|
||||
// Try to find another nomadic resource for this channel and return that.
|
||||
|
||||
// First, see if there's a hubloc for this site. Fetch that record to
|
||||
// obtain the nomadic identity hash. Then use that to find any additional
|
||||
// nomadic locations.
|
||||
|
||||
$h = Activity::get_actor_hublocs($resource, 'zot6');
|
||||
if ($h) {
|
||||
// mark this location deleted
|
||||
hubloc_delete($h[0]);
|
||||
$hubs = Activity::get_actor_hublocs($h[0]['hubloc_hash']);
|
||||
if ($hubs) {
|
||||
foreach ($hubs as $hub) {
|
||||
if ($hub['hubloc_id_url'] !== $resource && !$hub['hubloc_deleted']) {
|
||||
return self::exec($hub['hubloc_id_url'], $channel, $verify);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($x['success']) {
|
||||
if ($verify) {
|
||||
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
|
||||
|
||||
@@ -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" => ''
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,18 @@ class Queue {
|
||||
LibQueue::remove_by_posturl($_REQUEST['emptyhub']);
|
||||
}
|
||||
|
||||
$r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
|
||||
if($_REQUEST['deliverhub']) {
|
||||
|
||||
$hubq = q("SELECT * FROM outq WHERE outq_posturl = '%s'",
|
||||
dbesc($_REQUEST['deliverhub'])
|
||||
);
|
||||
|
||||
foreach ($hubq as $q) {
|
||||
LibQueue::deliver($q, true);
|
||||
}
|
||||
}
|
||||
|
||||
$r = dbq("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq
|
||||
where outq_delivered = 0 group by outq_posturl order by total desc");
|
||||
|
||||
for($x = 0; $x < count($r); $x ++) {
|
||||
@@ -37,6 +48,7 @@ class Queue {
|
||||
'$priority' => t('Priority'),
|
||||
'$desturl' => t('Destination URL'),
|
||||
'$nukehub' => t('Mark hub permanently offline'),
|
||||
'$deliverhub' => t('Retry delivery to this hub'),
|
||||
'$empty' => t('Empty queue for this hub'),
|
||||
'$lastconn' => t('Last known contact'),
|
||||
'$hasentries' => ((count($r)) ? true : false),
|
||||
|
||||
@@ -339,12 +339,15 @@ 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');
|
||||
|
||||
if (!in_array($default_role, array_keys($perm_roles))) {
|
||||
$default_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);
|
||||
|
||||
|
||||
$homelogin = get_config('system','login_on_homepage');
|
||||
$enable_context_help = get_config('system','enable_context_help');
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,19 +322,16 @@ 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'],
|
||||
'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop',
|
||||
'delete' => t('Delete'),
|
||||
'url' => chanlink_hash($rr['xchan_hash']),
|
||||
'webbie_label' => t('Channel address'),
|
||||
'webbie' => $rr['xchan_addr'],
|
||||
@@ -337,6 +342,7 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
'phone' => $phone,
|
||||
'status_label' => t('Status'),
|
||||
'status' => $status_str,
|
||||
'states' => $status,
|
||||
'connected_label' => t('Connected'),
|
||||
'connected' => datetime_convert('UTC',date_default_timezone_get(),$rr['abook_created'], 'c'),
|
||||
'approve_hover' => t('Approve connection'),
|
||||
@@ -349,13 +355,22 @@ 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']],
|
||||
'pending' => intval($rr['abook_pending'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$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 +386,30 @@ class Connections extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
else {
|
||||
$o .= "<script> var page_query = '" . escape_tags(urlencode($_GET['q'])) . "'; var extra_args = '" . extra_query_args() . "' ; </script>";
|
||||
$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'),
|
||||
'$approve' => t('Approve'),
|
||||
'$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 .= '<div id="content-complete"></div>';
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
675
Zotlabs/Module/Contactedit.php
Normal file
675
Zotlabs/Module/Contactedit.php
Normal file
@@ -0,0 +1,675 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/* @file Cobtactedit.php
|
||||
* @brief In this file the connection-editor form is generated and evaluated.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
use App;
|
||||
use Sabre\VObject\Reader;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use Zotlabs\Daemon\Master;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Web\HTTPHeaders;
|
||||
use Zotlabs\Lib\Permcat;
|
||||
use Zotlabs\Lib\AccessList;
|
||||
|
||||
require_once('include/socgraph.php');
|
||||
require_once('include/selectors.php');
|
||||
require_once('include/group.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
class Contactedit extends Controller {
|
||||
|
||||
/* @brief Initialize the connection-editor
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
function init() {
|
||||
|
||||
if (!local_channel())
|
||||
return;
|
||||
|
||||
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 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 = '<strong>';
|
||||
$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 .= '</strong><br>' . t('Location independence is not supported by their network.');
|
||||
}
|
||||
|
||||
$header_card = '<img src="' . $contact['xchan_photo_s'] . '" class="rounded" style="width: 3rem; height: 3rem;"> ' . $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'],
|
||||
'$roles_label' => t('Roles'),
|
||||
'$compare_label' => t('Compare permissions'),
|
||||
'$permission_label' => t('Permission'),
|
||||
'$pgroups_label' => t('Privacy groups'),
|
||||
'$profiles_label' => t('Profiles'),
|
||||
'$affinity_label' => t('Affinity'),
|
||||
'$filter_label' => t('Content filter')
|
||||
]);
|
||||
|
||||
$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'),
|
||||
],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/group.php');
|
||||
use Zotlabs\Lib\AccessList;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
|
||||
class Contactgroup extends \Zotlabs\Web\Controller {
|
||||
class Contactgroup extends Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
if(! local_channel()) {
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
if((argc() > 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -56,9 +56,10 @@ class Dreport extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select * from dreport where dreport_xchan = '%s' and dreport_mid = '%s'",
|
||||
$r = q("select * from dreport where dreport_xchan = '%s' and (dreport_mid = '%s' or dreport_mid = '%s')",
|
||||
dbesc($channel['channel_hash']),
|
||||
dbesc($mid)
|
||||
dbesc($mid),
|
||||
dbesc(str_replace('/item/', '/activity/', $mid))
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
|
||||
@@ -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 ]);
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
Libsync::build_sync_packet(local_channel(),null,true);
|
||||
}
|
||||
|
||||
goaway(z_root() . '/group/' . argv(1) . '/' . argv(2));
|
||||
}
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
$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) : ''));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -117,51 +130,32 @@ class Group extends Controller {
|
||||
|
||||
if((argc() == 1) || ((argc() == 2) && (argv(1) === 'new'))) {
|
||||
|
||||
$new = (((argc() == 2) && (argv(1) === 'new')) ? true : false);
|
||||
|
||||
$groups = q("SELECT id, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$i = 0;
|
||||
foreach($groups as $group) {
|
||||
$entries[$i]['name'] = $group['gname'];
|
||||
$entries[$i]['id'] = $group['id'];
|
||||
$entries[$i]['count'] = count(group_get_members($group['id']));
|
||||
$i++;
|
||||
}
|
||||
|
||||
$hookinfo = [ 'pgrp_extras' => '', 'group'=>argv(1) ];
|
||||
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'),
|
||||
'$add_new_label' => t('Add Group'),
|
||||
'$new' => $new,
|
||||
|
||||
// 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'),
|
||||
|
||||
// groups list
|
||||
'$title' => t('Privacy Groups'),
|
||||
'$name_label' => t('Name'),
|
||||
'$count_label' => t('Members'),
|
||||
'$entries' => $entries
|
||||
'$is_default_acl' => $is_default_acl,
|
||||
'$is_default_group' => $is_default_group,
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$context = array('$submit' => t('Submit'));
|
||||
$tpl = get_markup_template('group_edit.tpl');
|
||||
|
||||
@@ -174,7 +168,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 +209,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 +221,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,9 +246,9 @@ 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'),
|
||||
'$delete' => t('Delete'),
|
||||
'$form_security_token_drop' => get_form_security_token("group_drop"),
|
||||
'$pgrp_extras' => $pgrp_extras,
|
||||
);
|
||||
@@ -280,7 +274,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 +296,12 @@ class Group extends Controller {
|
||||
$context['$desc'] = t('Click a channel to toggle membership');
|
||||
$context['$pgrp_extras'] = $pgrp_extras;
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
$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);
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Zotlabs\Module;
|
||||
class Hcard extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else {
|
||||
@@ -13,12 +13,12 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
logger('hcard_request: ' . $which, LOGGER_DEBUG);
|
||||
|
||||
$profile = '';
|
||||
$channel = \App::get_channel();
|
||||
|
||||
|
||||
if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) {
|
||||
$which = $channel['channel_address'];
|
||||
$profile = argv(1);
|
||||
@@ -30,22 +30,22 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
$profile = '';
|
||||
$profile = $r[0]['profile_guid'];
|
||||
}
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/atom+xml',
|
||||
'title' => t('Posts and comments'),
|
||||
'href' => z_root() . '/feed/' . $which
|
||||
]);
|
||||
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
head_add_link( [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/atom+xml',
|
||||
'title' => t('Only posts'),
|
||||
'href' => z_root() . '/feed/' . $which . '?f=&top=1'
|
||||
]);
|
||||
|
||||
|
||||
|
||||
if(! $profile) {
|
||||
$x = q("select channel_id as profile_uid from channel where channel_address = '%s' limit 1",
|
||||
dbesc(argv(1))
|
||||
@@ -54,20 +54,20 @@ class Hcard extends \Zotlabs\Web\Controller {
|
||||
\App::$profile = $x[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
profile_load($which,$profile);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
$x = new \Zotlabs\Widget\Profile();
|
||||
$x = new \Zotlabs\Widget\Fullprofile();
|
||||
return $x->widget(array());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
|
||||
$item_normal = item_normal();
|
||||
$item_normal_update = item_normal_update();
|
||||
$sys = get_sys_channel();
|
||||
$sys_item = false;
|
||||
$sql_extra = '';
|
||||
|
||||
if(! $item_hash) {
|
||||
$r = q("SELECT mid FROM item
|
||||
@@ -77,11 +80,6 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
if($update && $_SESSION['loadtime'])
|
||||
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||
|
||||
$sys = get_sys_channel();
|
||||
$sql_extra = item_permissions_sql($sys['channel_id']);
|
||||
|
||||
$sys_item = false;
|
||||
|
||||
}
|
||||
|
||||
if(! $update) {
|
||||
@@ -183,6 +181,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(!$r) {
|
||||
$sys_item = true;
|
||||
$sql_extra = item_permissions_sql($sys['channel_id']);
|
||||
|
||||
$r = q("SELECT item.id AS item_id FROM item
|
||||
LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
|
||||
@@ -209,6 +208,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(!$r) {
|
||||
$sys_item = true;
|
||||
$sql_extra = item_permissions_sql($sys['channel_id']);
|
||||
|
||||
$r = q("SELECT item.parent AS item_id FROM item
|
||||
LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
|
||||
@@ -227,7 +227,7 @@ class Hq extends \Zotlabs\Web\Controller {
|
||||
if($r) {
|
||||
$items = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE parent = '%s' $item_normal ",
|
||||
WHERE parent = '%s' $item_normal $sql_extra",
|
||||
dbesc($r[0]['item_id'])
|
||||
);
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ class Item extends Controller {
|
||||
$consensus = intval($_REQUEST['consensus']);
|
||||
$nocomment = intval($_REQUEST['nocomment']);
|
||||
|
||||
$is_poll = ((trim($_REQUEST['poll_answers'][0]) != '' && trim($_REQUEST['poll_answers'][1]) != '') ? true : false);
|
||||
$is_poll = ((trim((string)$_REQUEST['poll_answers'][0]) != '' && trim((string)$_REQUEST['poll_answers'][1]) != '') ? true : false);
|
||||
|
||||
// 'origin' (if non-zero) indicates that this network is where the message originated,
|
||||
// for the purpose of relaying comments to other conversation members.
|
||||
@@ -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'];
|
||||
@@ -717,13 +719,13 @@ class Item extends Controller {
|
||||
}
|
||||
|
||||
|
||||
$location = notags(trim($_REQUEST['location']));
|
||||
$coord = notags(trim($_REQUEST['coord']));
|
||||
$verb = notags(trim($_REQUEST['verb']));
|
||||
$title = escape_tags(trim($_REQUEST['title']));
|
||||
$summary = trim($_REQUEST['summary']);
|
||||
$body = trim($_REQUEST['body']);
|
||||
$body .= trim($_REQUEST['attachment']);
|
||||
$location = notags(trim((string)$_REQUEST['location']));
|
||||
$coord = notags(trim((string)$_REQUEST['coord']));
|
||||
$verb = notags(trim((string)$_REQUEST['verb']));
|
||||
$title = escape_tags(trim((string)$_REQUEST['title']));
|
||||
$summary = trim((string)$_REQUEST['summary']);
|
||||
$body = trim((string)$_REQUEST['body']);
|
||||
$body .= trim((string)$_REQUEST['attachment']);
|
||||
$postopts = '';
|
||||
|
||||
$allow_empty = ((array_key_exists('allow_empty', $_REQUEST)) ? intval($_REQUEST['allow_empty']) : 0);
|
||||
@@ -762,7 +764,7 @@ class Item extends Controller {
|
||||
}
|
||||
|
||||
|
||||
$mimetype = notags(trim($_REQUEST['mimetype']));
|
||||
$mimetype = notags(trim((string)$_REQUEST['mimetype']));
|
||||
if (!$mimetype)
|
||||
$mimetype = 'text/bbcode';
|
||||
|
||||
@@ -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,23 @@ 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;
|
||||
$obj['name'] = $title;
|
||||
|
||||
$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 +1092,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 +1605,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);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use Zotlabs\Lib\AccessList;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
require_once('include/security.php');
|
||||
|
||||
class Lockview extends \Zotlabs\Web\Controller {
|
||||
class Lockview extends Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$atokens = array();
|
||||
$atokens = [];
|
||||
$atoken_xchans = [];
|
||||
$access_list = [];
|
||||
$guest_access_list = [];
|
||||
|
||||
if(local_channel()) {
|
||||
if (local_channel()) {
|
||||
$at = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($at) {
|
||||
foreach($at as $t) {
|
||||
$atokens[] = atoken_xchan($t);
|
||||
if ($at) {
|
||||
foreach ($at as $t) {
|
||||
$atoken_xchan = atoken_xchan($t);
|
||||
$atokens[] = array_merge($t, $atoken_xchan);
|
||||
$atoken_xchans[] = $atoken_xchan['xchan_hash'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,20 +32,20 @@ class Lockview extends \Zotlabs\Web\Controller {
|
||||
$type = ((argc() > 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);
|
||||
}
|
||||
|
||||
if(! $item_id)
|
||||
if (!$item_id)
|
||||
killme();
|
||||
|
||||
if (! in_array($type, array('item', 'photo', 'attach', 'event', 'menu_item', 'chatroom')))
|
||||
if (!in_array($type, ['item', 'photo', 'attach', 'menu_item', 'chatroom']))
|
||||
killme();
|
||||
|
||||
// we have different naming in in menu_item table and chatroom table
|
||||
switch($type) {
|
||||
switch ($type) {
|
||||
case 'menu_item':
|
||||
$id = 'mitem_id';
|
||||
break;
|
||||
@@ -53,134 +62,177 @@ class Lockview extends \Zotlabs\Web\Controller {
|
||||
intval($item_id)
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
if (!$r)
|
||||
killme();
|
||||
|
||||
$item = $r[0];
|
||||
$uid = null;
|
||||
$url = '';
|
||||
|
||||
//we have different naming in in menu_item table and chatroom table
|
||||
switch($type) {
|
||||
switch ($type) {
|
||||
case 'menu_item':
|
||||
$uid = $item['mitem_channel_id'];
|
||||
break;
|
||||
case 'chatroom':
|
||||
$uid = $item['cr_uid'];
|
||||
$uid = $item['cr_uid'];
|
||||
$channel = channelx_by_n($uid);
|
||||
$url = z_root() . '/chat/' . $channel['channel_address'] . '/' . $item['cr_id'];
|
||||
break;
|
||||
case 'item':
|
||||
$uid = $item['uid'];
|
||||
$url = $item['plink'];
|
||||
break;
|
||||
case 'photo':
|
||||
$uid = $item['uid'];
|
||||
$channel = channelx_by_n($uid);
|
||||
$url = z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $item['resource_id'];
|
||||
break;
|
||||
case 'attach':
|
||||
$uid = $item['uid'];
|
||||
$channel = channelx_by_n($uid);
|
||||
$url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $item['display_path'];
|
||||
break;
|
||||
default:
|
||||
$uid = $item['uid'];
|
||||
break;
|
||||
}
|
||||
|
||||
if($uid != local_channel()) {
|
||||
echo '<div class="dropdown-item">' . t('Remote privacy information not available.') . '</div>';
|
||||
if (intval($uid) !== local_channel()) {
|
||||
echo '<div class="dropdown-item-text">' . t('Remote privacy information not available') . '</div>';
|
||||
killme();
|
||||
}
|
||||
|
||||
if(intval($item['item_private']) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid']))
|
||||
&& (! strlen($item['deny_cid'])) && (! strlen($item['deny_gid']))) {
|
||||
if (intval($item['item_private']) && (!strlen($item['allow_cid'])) && (!strlen($item['allow_gid']))
|
||||
&& (!strlen($item['deny_cid'])) && (!strlen($item['deny_gid']))) {
|
||||
|
||||
// if the post is private, but public_policy is blank ("visible to the internet"), and there aren't any
|
||||
// specific recipients, we're the recipient of a post with "bcc" or targeted recipients; so we'll just show it
|
||||
// as unknown specific recipients. The sender will have the visibility list and will fall through to the
|
||||
// next section.
|
||||
|
||||
echo '<div class="dropdown-item">' . translate_scope((! $item['public_policy']) ? 'specific' : $item['public_policy']) . '</div>';
|
||||
echo '<div class="dropdown-item-text">' . translate_scope((!$item['public_policy']) ? 'specific' : $item['public_policy']) . '</div>';
|
||||
killme();
|
||||
}
|
||||
|
||||
$allowed_users = expand_acl($item['allow_cid']);
|
||||
$allowed_users = expand_acl($item['allow_cid']);
|
||||
$allowed_groups = expand_acl($item['allow_gid']);
|
||||
$deny_users = expand_acl($item['deny_cid']);
|
||||
$deny_groups = expand_acl($item['deny_gid']);
|
||||
$deny_users = expand_acl($item['deny_cid']);
|
||||
$deny_groups = expand_acl($item['deny_gid']);
|
||||
|
||||
$o = '<div class="dropdown-item">' . t('Visible to:') . '</div>';
|
||||
$l = array();
|
||||
|
||||
stringify_array_elms($allowed_groups,true);
|
||||
stringify_array_elms($allowed_users,true);
|
||||
stringify_array_elms($deny_groups,true);
|
||||
stringify_array_elms($deny_users,true);
|
||||
stringify_array_elms($allowed_groups, true);
|
||||
stringify_array_elms($allowed_users, true);
|
||||
stringify_array_elms($deny_groups, true);
|
||||
stringify_array_elms($deny_users, true);
|
||||
|
||||
$allowed_xchans = [];
|
||||
|
||||
$profile_groups = [];
|
||||
if($allowed_groups) {
|
||||
foreach($allowed_groups as $g) {
|
||||
if(substr($g,0,4) === '\'vp.') {
|
||||
$profile_groups[] = '\'' . substr($g,4);
|
||||
if ($allowed_groups) {
|
||||
foreach ($allowed_groups as $g) {
|
||||
if (substr($g, 0, 4) === '\'vp.') {
|
||||
$profile_groups[] = '\'' . substr($g, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
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[] = '<div class="dropdown-item"><b>' . t('Profile','acl') . ' ' . $rr['profile_name'] . '</b></div>';
|
||||
|
||||
if ($profile_groups) {
|
||||
$r = q("SELECT id, profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$pgrp_members = AccessList::profile_members_xchan($uid, $rr['id']);
|
||||
$allowed_xchans = array_merge($allowed_xchans, $pgrp_members);
|
||||
$access_list[] = '<div class="dropdown-item-text" title="' . t('Profile', 'acl') . '">' . $rr['profile_name'] . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($allowed_groups)) {
|
||||
$r = q("SELECT gname FROM pgrp WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item"><b>' . $rr['gname'] . '</b></div>';
|
||||
if ($allowed_groups) {
|
||||
$r = q("SELECT id, gname FROM pgrp WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$pgrp_members = AccessList::members_xchan($uid, $rr['id']);
|
||||
$allowed_xchans = array_merge($allowed_xchans, $pgrp_members);
|
||||
$access_list[] = '<div class="dropdown-item-text" title="' . t('Privacy group') . '">' . $rr['gname'] . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count($allowed_users)) {
|
||||
$r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ',$allowed_users) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item">' . $rr['xchan_name'] . '</div>';
|
||||
if($atokens) {
|
||||
foreach($atokens as $at) {
|
||||
if(in_array("'" . $at['xchan_hash'] . "'",$allowed_users)) {
|
||||
$l[] = '<div class="dropdown-item">' . $at['xchan_name'] . '</div>';
|
||||
|
||||
if ($allowed_users) {
|
||||
$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'];
|
||||
if (!in_array($rr['xchan_hash'], $atoken_xchans)) {
|
||||
$access_list[] = '<div class="dropdown-item-text">' . $rr['xchan_name'] . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$profile_groups = [];
|
||||
if($deny_groups) {
|
||||
foreach($deny_groups as $g) {
|
||||
if(substr($g,0,4) === '\'vp.') {
|
||||
$profile_groups[] = '\'' . substr($g,4);
|
||||
if ($deny_groups) {
|
||||
foreach ($deny_groups as $g) {
|
||||
if (substr($g, 0, 4) === '\'vp.') {
|
||||
$profile_groups[] = '\'' . substr($g, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count($profile_groups)) {
|
||||
|
||||
if ($profile_groups) {
|
||||
$r = q("SELECT profile_name FROM profile WHERE profile_guid IN ( " . implode(', ', $profile_groups) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item"><b><strike>' . t('Profile','acl') . ' ' . $rr['profile_name'] . '</strike></b></div>';
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$access_list[] = '<div class="dropdown-item-text" title="' . t('Profile', 'acl') . '"><strike>' . $rr['profile_name'] . '</strike></b></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(count($deny_groups)) {
|
||||
if ($deny_groups) {
|
||||
$r = q("SELECT gname FROM pgrp WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
|
||||
if($r)
|
||||
foreach($r as $rr)
|
||||
$l[] = '<div class="dropdown-item"><b><strike>' . $rr['gname'] . '</strike></b></div>';
|
||||
}
|
||||
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[] = '<div class="dropdown-item"><strike>' . $rr['xchan_name'] . '</strike></div>';
|
||||
|
||||
if($atokens) {
|
||||
foreach($atokens as $at) {
|
||||
if(in_array("'" . $at['xchan_hash'] . "'",$deny_users)) {
|
||||
$l[] = '<div class="dropdown-item"><strike>' . $at['xchan_name'] . '</strike></div>';
|
||||
}
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$access_list[] = '<div class="dropdown-item-text" title="' . t('Privacy group') . '"><strike>' . $rr['gname'] . '</strike></b></div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo $o . implode($l);
|
||||
killme();
|
||||
if ($deny_users) {
|
||||
$r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )");
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
$access_list[] = '<div class="dropdown-item-text"><strike>' . $rr['xchan_name'] . '</strike></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($atokens && $allowed_xchans && $url) {
|
||||
|
||||
$guest_access_list = [];
|
||||
|
||||
$allowed_xchans = array_unique($allowed_xchans);
|
||||
foreach ($atokens as $atoken) {
|
||||
if (in_array($atoken['xchan_hash'], $allowed_xchans)) {
|
||||
$guest_access_list[] = '<div class="dropdown-item d-flex justify-content-between cursor-pointer" title="' . sprintf(t('Click to copy link to this ressource for guest %s to clipboard'), $atoken['xchan_name']) . '" data-token="' . $url . '?zat=' . $atoken['atoken_token'] . '" onclick="navigator.clipboard.writeText(this.dataset.token); $.jGrowl(\'' . t('Link copied') . '\', { sticky: false, theme: \'info\', life: 1000 });"><span>' . $atoken['xchan_name'] . '</span><i class="fa fa-copy p-1"></i></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$access_list_header = '';
|
||||
if ($access_list) {
|
||||
$access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('Access') . '</div>';
|
||||
}
|
||||
|
||||
$guest_access_list_header = '';
|
||||
if ($guest_access_list) {
|
||||
$guest_access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('Guest access') . '</div>';
|
||||
}
|
||||
|
||||
$divider = '';
|
||||
if ($access_list && $guest_access_list) {
|
||||
$divider = '<div class="dropdown-divider"></div>';
|
||||
}
|
||||
|
||||
echo $access_list_header . implode($access_list) . $divider . $guest_access_list_header . implode($guest_access_list);
|
||||
killme();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,15 @@ namespace Zotlabs\Module;
|
||||
use App;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\System;
|
||||
use Zotlabs\Render\Theme;
|
||||
|
||||
class Manifest extends Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
// populate App::$theme_info
|
||||
Theme::current();
|
||||
|
||||
$ret = [
|
||||
'name' => ucfirst(System::get_platform_name()),
|
||||
'short_name' => ucfirst(System::get_platform_name()),
|
||||
@@ -18,12 +22,13 @@ class Manifest extends Controller {
|
||||
[ 'src' => '/images/app/hz-128.png', 'sizes' => '128x128', 'type' => 'image/png' ],
|
||||
[ 'src' => '/images/app/hz-144.png', 'sizes' => '144x144', 'type' => 'image/png' ],
|
||||
[ 'src' => '/images/app/hz-152.png', 'sizes' => '152x152', 'type' => 'image/png' ],
|
||||
[ 'src' => '/images/app/hz-192.png', 'sizes' => '192x192', 'type' => 'image/png' ],
|
||||
[ 'src' => '/images/app/hz-192.png', 'sizes' => '192x192', 'type' => 'image/png', 'purpose' => 'any maskable' ],
|
||||
[ 'src' => '/images/app/hz-348.png', 'sizes' => '384x384', 'type' => 'image/png' ],
|
||||
[ 'src' => '/images/app/hz-512.png', 'sizes' => '512x512', 'type' => 'image/png' ],
|
||||
[ 'src' => '/images/app/hz.svg', 'sizes' => '64x64', 'type' => 'image/xml+svg' ]
|
||||
],
|
||||
'theme_color' => '#343a40',
|
||||
'theme_color' => App::$theme_info['theme_color'],
|
||||
'background_color' => App::$theme_info['background_color'],
|
||||
'scope' => '/',
|
||||
'start_url' => z_root(),
|
||||
'display' => 'standalone',
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use Zotlabs\Lib\Group;
|
||||
use Zotlabs\Lib\AccessList;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use App;
|
||||
|
||||
require_once('include/items.php');
|
||||
require_once('include/group.php');
|
||||
require_once('include/contact_widgets.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
@@ -233,7 +232,7 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
if($group) {
|
||||
|
||||
$contact_str = '';
|
||||
$contacts = group_get_members($group);
|
||||
$contacts = AccessList::members(local_channel(), $group);
|
||||
if($contacts) {
|
||||
$contact_str = ids_to_querystr($contacts, 'xchan', true);
|
||||
}
|
||||
@@ -246,7 +245,7 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
$item_thread_top = '';
|
||||
$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($group_hash) . '>%') . "' ) 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(
|
||||
|
||||
@@ -138,7 +138,7 @@ class New_channel extends \Zotlabs\Web\Controller {
|
||||
intval($aid)
|
||||
);
|
||||
if($r && (! intval($r[0]['total']))) {
|
||||
$default_role = get_config('system','default_permissions_role','social');
|
||||
$default_role = get_config('system','default_permissions_role','personal');
|
||||
}
|
||||
|
||||
$limit = account_service_class_fetch(get_account_id(),'total_identities');
|
||||
@@ -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.') . '<br>' . '<a href="help/member/member_guide#Channel_Permission_Roles" target="_blank">' . t('Read more about channel permission roles') . '</a>',$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'),
|
||||
|
||||
@@ -3,49 +3,156 @@
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Apps;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use Zotlabs\Lib\AccessList;
|
||||
use Zotlabs\Lib\Permcat;
|
||||
|
||||
class Permcats extends Controller {
|
||||
|
||||
function post() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
if(! Apps::system_app_installed(local_channel(), 'Permission Categories'))
|
||||
if (!local_channel())
|
||||
return;
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
check_form_security_token_redirectOnErr('/permcats', 'permcats');
|
||||
|
||||
$name = escape_tags(trim($_REQUEST['name']));
|
||||
$is_system_role = isset($_REQUEST['is_system_role']);
|
||||
$return_path = z_root() . '/permcats/' . $_REQUEST['return_path'];
|
||||
$group_hash = $_REQUEST['group_select'] ?? '';
|
||||
$deleted_role = $_REQUEST['deleted_role'] ?? '';
|
||||
$new_role = $_REQUEST['new_role'] ?? '';
|
||||
$contacts = [];
|
||||
|
||||
$all_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
|
||||
$name = escape_tags(trim($_POST['name']));
|
||||
if(! $name) {
|
||||
notice( t('Permission category name is required.') . EOL);
|
||||
if (argv(1) && hex2bin(argv(1)) !== $name) {
|
||||
$return_path = z_root() . '/permcats/' . bin2hex($name);
|
||||
}
|
||||
|
||||
if ($deleted_role && $new_role) {
|
||||
$r = q("SELECT abook_xchan FROM abook WHERE abook_channel = %d AND abook_role = '%s' AND abook_self = 0 AND abook_pending = 0",
|
||||
intval(local_channel()),
|
||||
dbesc($deleted_role)
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
$contacts = ids_to_array($r, 'abook_xchan');
|
||||
}
|
||||
|
||||
if ($contacts) {
|
||||
Permcat::assign($channel, $new_role, $contacts);
|
||||
}
|
||||
|
||||
Permcat::delete(local_channel(), $deleted_role);
|
||||
|
||||
$default_role = get_pconfig(local_channel(), 'system', 'default_permcat', 'default');
|
||||
if ($deleted_role === $default_role) {
|
||||
set_pconfig(local_channel(), 'system', 'default_permcat', $new_role);
|
||||
}
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
info(t('Contact role deleted.') . EOL);
|
||||
|
||||
goaway(z_root() . '/permcats/' . bin2hex($new_role));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
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())
|
||||
);
|
||||
|
||||
$pcarr = [];
|
||||
if ($r) {
|
||||
$contacts = ids_to_array($r, 'abook_xchan');
|
||||
}
|
||||
}
|
||||
|
||||
if($all_perms) {
|
||||
foreach($all_perms as $perm => $desc) {
|
||||
if(array_key_exists('perms_' . $perm, $_POST)) {
|
||||
$group = null;
|
||||
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($_REQUEST['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) {
|
||||
Permcat::assign($channel, $name, $contacts);
|
||||
}
|
||||
|
||||
info(t('Contact role saved.') . EOL);
|
||||
Libsync::build_sync_packet();
|
||||
goaway($return_path);
|
||||
return;
|
||||
}
|
||||
|
||||
$pcarr = [];
|
||||
$all_perms = Permissions::Perms();
|
||||
|
||||
if ($all_perms) {
|
||||
foreach ($all_perms as $perm => $desc) {
|
||||
if (array_key_exists('perms_' . $perm, $_POST)) {
|
||||
$pcarr[] = $perm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\Zotlabs\Lib\Permcat::update(local_channel(),$name,$pcarr);
|
||||
$pcat = new Permcat(local_channel());
|
||||
$pcatlist = $pcat->listing();
|
||||
$existing_raw_perms = [];
|
||||
|
||||
if ($pcatlist) {
|
||||
foreach ($pcatlist as $pc) {
|
||||
if ($pc['name'] && ($pc['name'] === $name)) {
|
||||
$existing_raw_perms = $pc['raw_perms'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$contacts && array_diff_assoc($existing_raw_perms, Permissions::FilledPerms($pcarr))) {
|
||||
// If we don't have anyone to assign the role to and an existing role has changed,
|
||||
// we will re-assign the changed role to all its members if there are any.
|
||||
|
||||
$r = q("SELECT abook_xchan FROM abook WHERE abook_channel = %d AND abook_role = '%s' AND abook_self = 0 AND abook_pending = 0",
|
||||
intval(local_channel()),
|
||||
dbesc($name)
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
$contacts = ids_to_array($r, 'abook_xchan');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Permcat::update(local_channel(), $name, $pcarr);
|
||||
|
||||
if ($contacts) {
|
||||
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;
|
||||
}
|
||||
@@ -53,79 +160,107 @@ class Permcats extends Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
if (!local_channel())
|
||||
return EMPTY_STR;
|
||||
|
||||
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');
|
||||
}
|
||||
nav_set_selected('Contact Roles');
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
if(argc() > 1)
|
||||
$name = '';
|
||||
if (argc() > 1) {
|
||||
$name = hex2bin(argv(1));
|
||||
|
||||
if(argc() > 2 && argv(2) === 'drop') {
|
||||
\Zotlabs\Lib\Permcat::delete(local_channel(),$name);
|
||||
Libsync::build_sync_packet();
|
||||
json_return_and_die([ 'success' => true ]);
|
||||
}
|
||||
|
||||
$perms = [];
|
||||
$existing = [];
|
||||
$pcat = new Permcat(local_channel());
|
||||
$pcatlist = $pcat->listing();
|
||||
$is_system_role = false;
|
||||
$delete_role_select_options = [];
|
||||
$is_default_role = (get_pconfig(local_channel(), 'system', 'default_permcat', 'default') === $name);
|
||||
$localname = '';
|
||||
|
||||
$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();
|
||||
$permcats = [];
|
||||
if($pcatlist) {
|
||||
foreach($pcatlist as $pc) {
|
||||
if(($pc['name']) && ($name) && ($pc['name'] == $name))
|
||||
if ($pcatlist) {
|
||||
foreach ($pcatlist as $pc) {
|
||||
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'];
|
||||
}
|
||||
|
||||
if ($pc['name'] == $name) {
|
||||
$localname = $pc['localname'];
|
||||
}
|
||||
|
||||
if ($pc['name'] !== $name) {
|
||||
$delete_role_select_options[$pc['name']] = $pc['localname'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
// select for delete action
|
||||
$delete_role_select = [
|
||||
'new_role',
|
||||
(($is_default_role) ? t('Role to assign affected contacts and default role to') : t('Role to assign affected contacts to')),
|
||||
'',
|
||||
'',
|
||||
$delete_role_select_options
|
||||
];
|
||||
|
||||
foreach($global_perms as $k => $v) {
|
||||
$thisperm = \Zotlabs\Lib\Permcat::find_permcat($existing,$k);
|
||||
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
|
||||
$global_perms = Permissions::Perms();
|
||||
|
||||
if($existing[$k])
|
||||
$thisperm = "1";
|
||||
foreach ($global_perms as $k => $v) {
|
||||
$thisperm = Permcat::find_permcat($existing, $k);
|
||||
$checkinherited = PermissionLimits::Get(local_channel(), $k);
|
||||
|
||||
$perms[] = array('perms_' . $k, $v, '',$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
|
||||
if ($existing[$k])
|
||||
$thisperm = 1;
|
||||
|
||||
$perms[] = [
|
||||
'perms_' . $k,
|
||||
$v,
|
||||
'',
|
||||
$thisperm,
|
||||
1,
|
||||
(($checkinherited & PERMS_SPECIFIC) ? '' : '1'),
|
||||
'',
|
||||
$checkinherited
|
||||
];
|
||||
}
|
||||
|
||||
$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(
|
||||
$o = replace_macros($tpl, [
|
||||
'$form_security_token' => get_form_security_token("permcats"),
|
||||
'$title' => t('Permission Categories'),
|
||||
'$desc' => $desc,
|
||||
'$desc2' => $desc2,
|
||||
'$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') . ' <span class="required">*</span>', (($name) ? $name : ''), ''),
|
||||
'$me' => t('My Settings'),
|
||||
'$perms' => $perms,
|
||||
'$inherited' => t('inherited'),
|
||||
'$notself' => 0,
|
||||
'$self' => 1,
|
||||
'$permlbl' => t('Individual Permissions'),
|
||||
'$permnote' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here.'),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
'$default_role' => ['default_role', t('Automatically assign this role to new contacts'), intval($is_default_role), '', [t('No'), t('Yes')]],
|
||||
'$title' => t('Contact Roles'),
|
||||
'$name' => ['name', t('Role name') . ' <span class="required">*</span>', (($localname) ? $localname : ''), (($is_system_role) ? t('System role - not editable') : ''), '', (($is_system_role) ? 'disabled' : '')],
|
||||
'$delete_label' => t('Deleting') . ' ' . $localname,
|
||||
'$current_role' => $name,
|
||||
'$perms' => $perms,
|
||||
'$inherited' => t('inherited'),
|
||||
'$is_system_role' => $is_system_role,
|
||||
'$permlbl' => t('Role Permissions'),
|
||||
'$permnote' => t('Some permissions may be inherited from your <a href="settings">channel role</a>, which have higher priority than contact role settings.'),
|
||||
'$submit' => t('Submit'),
|
||||
'$return_path' => argv(1),
|
||||
'$group_select' => $group_select,
|
||||
'$delete_role_select' => $delete_role_select,
|
||||
'$delet_role_button' => t('Delete')
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Daemon\Master;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
/*
|
||||
* @file Profile_photo.php
|
||||
@@ -15,109 +19,123 @@ require_once('include/photos.php');
|
||||
require_once('include/channel.php');
|
||||
|
||||
/* @brief Function for sync'ing permissions of profile-photos and their profile
|
||||
*
|
||||
* @param $profileid The id number of the profile to sync
|
||||
* @return void
|
||||
*/
|
||||
|
||||
|
||||
class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
*
|
||||
*/
|
||||
class Profile_photo extends Controller {
|
||||
|
||||
|
||||
/* @brief Initalize the profile-photo edit view
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function init() {
|
||||
|
||||
if(! local_channel()) {
|
||||
if (!local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
profile_load($channel['channel_address']);
|
||||
$channel = App::get_channel();
|
||||
$profile = App::$argv[1];
|
||||
|
||||
profile_load($channel['channel_address'], $profile);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* @brief Evaluate posted values
|
||||
*
|
||||
* @param $a Current application
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function post() {
|
||||
|
||||
if(! local_channel()) {
|
||||
if (!local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$channel = App::get_channel();
|
||||
|
||||
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
||||
|
||||
// Remove cover photo
|
||||
if(isset($_POST['remove'])) {
|
||||
$r = q("select id, profile_guid, is_default, gender from profile where uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$r = q("SELECT resource_id FROM photo WHERE photo_usage = %d AND uid = %d LIMIT 1",
|
||||
intval(PHOTO_PROFILE),
|
||||
intval(local_channel())
|
||||
);
|
||||
$profile_id = intval($_POST['profile']);
|
||||
$default_profile_id = null;
|
||||
$profile = [];
|
||||
|
||||
if($r) {
|
||||
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_PROFILE),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$sync = attach_export_data($channel,$r[0]['resource_id']);
|
||||
if($sync)
|
||||
Libsync:: build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
foreach ($r as $rr) {
|
||||
if ($rr['is_default']) {
|
||||
$default_profile_id = intval($rr['id']);
|
||||
}
|
||||
|
||||
if ($profile_id === intval($rr['id'])) {
|
||||
$profile = $rr;
|
||||
}
|
||||
}
|
||||
|
||||
$is_default_profile = ($profile_id === $default_profile_id);
|
||||
|
||||
// Remove profile photo
|
||||
if (isset($_POST['remove'])) {
|
||||
|
||||
if ($is_default_profile) {
|
||||
|
||||
$r = q("SELECT resource_id FROM photo WHERE photo_usage = %d AND uid = %d LIMIT 1",
|
||||
intval(PHOTO_PROFILE),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_PROFILE),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
q("update profile set photo = '%s', thumb = '%s' where is_default = 1 and uid = %d",
|
||||
dbesc(z_root() . '/photo/profile/l/' . local_channel()),
|
||||
dbesc(z_root() . '/photo/profile/m/' . local_channel()),
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d",
|
||||
dbesc(z_root() . '/' . get_default_profile_photo(300)),
|
||||
dbesc(z_root() . '/' . get_default_profile_photo(80)),
|
||||
intval($profile_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
|
||||
$sync = attach_export_data($channel, $r[0]['resource_id']);
|
||||
if ($sync)
|
||||
Libsync:: build_sync_packet($channel['channel_id'], ['file' => [$sync]]);
|
||||
|
||||
$_SESSION['reload_avatar'] = true;
|
||||
|
||||
goaway(z_root() . '/profiles');
|
||||
goaway(z_root() . '/profiles/' . $profile_id);
|
||||
}
|
||||
|
||||
if((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
|
||||
if ((array_key_exists('cropfinal', $_POST)) && (intval($_POST['cropfinal']) == 1)) {
|
||||
|
||||
// logger('crop: ' . print_r($_POST,true));
|
||||
|
||||
// phase 2 - we have finished cropping
|
||||
|
||||
if(argc() != 2) {
|
||||
notice( t('Image uploaded but image cropping failed.') . EOL );
|
||||
if (argc() != 2) {
|
||||
notice(t('Image uploaded but image cropping failed.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$image_id = argv(1);
|
||||
|
||||
if(substr($image_id,-2,1) == '-') {
|
||||
$scale = substr($image_id,-1,1);
|
||||
$image_id = substr($image_id,0,-2);
|
||||
if (substr($image_id, -2, 1) == '-') {
|
||||
$scale = substr($image_id, -1, 1);
|
||||
$image_id = substr($image_id, 0, -2);
|
||||
}
|
||||
|
||||
|
||||
// unless proven otherwise
|
||||
$is_default_profile = 1;
|
||||
|
||||
if($_REQUEST['profile']) {
|
||||
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
|
||||
intval($_REQUEST['profile']),
|
||||
intval(local_channel())
|
||||
);
|
||||
if($r) {
|
||||
$profile = $r[0];
|
||||
if(! intval($profile['is_default']))
|
||||
$is_default_profile = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$srcX = intval($_POST['xstart']);
|
||||
$srcY = intval($_POST['ystart']);
|
||||
$srcW = intval($_POST['xfinal']) - $srcX;
|
||||
@@ -126,16 +144,18 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
|
||||
dbesc($image_id),
|
||||
dbesc(local_channel()),
|
||||
intval($scale));
|
||||
if($r) {
|
||||
intval($scale)
|
||||
);
|
||||
|
||||
$base_image = $r[0];
|
||||
if ($r) {
|
||||
|
||||
$base_image = $r[0];
|
||||
$base_image['content'] = (($r[0]['os_storage']) ? @file_get_contents(dbunescbin($base_image['content'])) : dbunescbin($base_image['content']));
|
||||
|
||||
$im = photo_factory($base_image['content'], $base_image['mimetype']);
|
||||
if($im->is_valid()) {
|
||||
if ($im->is_valid()) {
|
||||
|
||||
$im->cropImage(300,$srcX,$srcY,$srcW,$srcH);
|
||||
$im->cropImage(300, $srcX, $srcY, $srcW, $srcH);
|
||||
|
||||
$aid = get_account_id();
|
||||
|
||||
@@ -147,12 +167,10 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
'album' => t('Profile Photos'),
|
||||
'os_path' => $base_image['os_path'],
|
||||
'display_path' => $base_image['display_path'],
|
||||
'photo_usage' => PHOTO_PROFILE,
|
||||
'edited' => dbescdate($base_image['edited'])
|
||||
'photo_usage' => (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL),
|
||||
'edited' => dbescdate($base_image['edited'])
|
||||
];
|
||||
|
||||
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
|
||||
|
||||
$r1 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_300);
|
||||
|
||||
$im->scaleImage(80);
|
||||
@@ -161,10 +179,10 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
$im->scaleImage(48);
|
||||
$r3 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_48);
|
||||
|
||||
if($r1 === false || $r2 === false || $r3 === false) {
|
||||
if ($r1 === false || $r2 === false || $r3 === false) {
|
||||
// if one failed, delete them all so we can start over.
|
||||
notice( t('Image resize failed.') . EOL );
|
||||
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d )",
|
||||
notice(t('Image resize failed.') . EOL);
|
||||
q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d )",
|
||||
dbesc($base_image['resource_id']),
|
||||
local_channel(),
|
||||
intval(PHOTO_RES_PROFILE_300),
|
||||
@@ -179,8 +197,8 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
intval(PHOTO_RES_PROFILE_80),
|
||||
intval(PHOTO_RES_PROFILE_48)
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xx) {
|
||||
if ($x) {
|
||||
foreach ($x as $xx) {
|
||||
@unlink(dbunescbin($xx['content']));
|
||||
}
|
||||
}
|
||||
@@ -190,16 +208,14 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
// If setting for the default profile, unset the profile photo flag from any other photos I own
|
||||
|
||||
if($is_default_profile) {
|
||||
|
||||
$r = q("update profile set photo = '%s', thumb = '%s' where is_default = 1 and uid = %d",
|
||||
if ($is_default_profile) {
|
||||
q("update profile set photo = '%s', thumb = '%s' where is_default = 1 and uid = %d",
|
||||
dbesc(z_root() . '/photo/profile/l/' . local_channel()),
|
||||
dbesc(z_root() . '/photo/profile/m/' . local_channel()),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
$r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d
|
||||
q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d
|
||||
AND resource_id != '%s' AND uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_PROFILE),
|
||||
@@ -207,15 +223,13 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
send_profile_photo_activity($channel,$base_image,$profile);
|
||||
|
||||
send_profile_photo_activity($channel, $base_image, $profile);
|
||||
}
|
||||
else {
|
||||
$r = q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d",
|
||||
q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d",
|
||||
dbesc(z_root() . '/photo/' . $base_image['resource_id'] . '-4'),
|
||||
dbesc(z_root() . '/photo/' . $base_image['resource_id'] . '-5'),
|
||||
intval($_REQUEST['profile']),
|
||||
intval($profile_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
}
|
||||
@@ -223,7 +237,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
// set $send to false in profiles_build_sync() to return the data
|
||||
// so that we only send one sync packet.
|
||||
|
||||
$sync_profiles = profiles_build_sync(local_channel(),false);
|
||||
$sync_profiles = profiles_build_sync(local_channel(), false);
|
||||
|
||||
// We'll set the updated profile-photo timestamp even if it isn't the default profile,
|
||||
// so that browsers will do a cache update unconditionally
|
||||
@@ -231,7 +245,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
// changed to a generic URL by a clone operation. Otherwise the new photo may
|
||||
// not get pushed to other sites correctly.
|
||||
|
||||
$r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s'
|
||||
q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s'
|
||||
where xchan_hash = '%s'",
|
||||
dbesc($im->getType()),
|
||||
dbescdate($base_image['edited']),
|
||||
@@ -241,79 +255,123 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
dbesc($channel['xchan_hash'])
|
||||
);
|
||||
|
||||
photo_profile_setperms(local_channel(),$base_image['resource_id'],$_REQUEST['profile']);
|
||||
photo_profile_setperms(local_channel(), $base_image['resource_id'], $profile_id);
|
||||
|
||||
$sync = attach_export_data($channel,$base_image['resource_id']);
|
||||
if($sync)
|
||||
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync), 'profile' => $sync_profiles));
|
||||
$sync = attach_export_data($channel, $base_image['resource_id']);
|
||||
if ($sync)
|
||||
Libsync::build_sync_packet($channel['channel_id'], ['file' => [$sync], 'profile' => $sync_profiles]);
|
||||
|
||||
|
||||
// Similarly, tell the nav bar to bypass the cache and update the avatar image.
|
||||
$_SESSION['reload_avatar'] = true;
|
||||
|
||||
info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
|
||||
info(t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
|
||||
|
||||
// Update directory in background
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory',$channel['channel_id']));
|
||||
Master::Summon(['Directory', $channel['channel_id']]);
|
||||
|
||||
}
|
||||
else
|
||||
notice( t('Unable to process image') . EOL);
|
||||
notice(t('Unable to process image') . EOL);
|
||||
}
|
||||
|
||||
goaway(z_root() . '/profiles');
|
||||
goaway(z_root() . '/profiles/' . $profile_id);
|
||||
return; // NOTREACHED
|
||||
}
|
||||
|
||||
// A new photo was uploaded. Store it and save some important details
|
||||
// in App::$data for use in the cropping function
|
||||
|
||||
|
||||
$hash = photo_new_resource();
|
||||
$hash = photo_new_resource();
|
||||
$importing = false;
|
||||
$smallest = 0;
|
||||
$smallest = 0;
|
||||
|
||||
|
||||
if($_REQUEST['importfile']) {
|
||||
$hash = $_REQUEST['importfile'];
|
||||
if ($_REQUEST['importfile']) {
|
||||
$hash = $_REQUEST['importfile'];
|
||||
$importing = true;
|
||||
}
|
||||
else {
|
||||
require_once('include/attach.php');
|
||||
$res = attach_store(\App::get_channel(), get_observer_hash(), '', array('album' => t('Profile Photos'), 'hash' => $hash, 'nosync' => true, 'source' => 'photos'));
|
||||
|
||||
$matches = [];
|
||||
$partial = false;
|
||||
|
||||
if (array_key_exists('HTTP_CONTENT_RANGE', $_SERVER)) {
|
||||
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/', $_SERVER['HTTP_CONTENT_RANGE'], $matches);
|
||||
if ($pm) {
|
||||
logger('Content-Range: ' . print_r($matches, true));
|
||||
$partial = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($partial) {
|
||||
$x = save_chunk($channel, $matches[1], $matches[2], $matches[3]);
|
||||
|
||||
if ($x['partial']) {
|
||||
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
|
||||
json_return_and_die($x);
|
||||
}
|
||||
else {
|
||||
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
|
||||
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $x['name'],
|
||||
'type' => $x['type'],
|
||||
'tmp_name' => $x['tmp_name'],
|
||||
'error' => $x['error'],
|
||||
'size' => $x['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!array_key_exists('userfile', $_FILES)) {
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $_FILES['files']['name'],
|
||||
'type' => $_FILES['files']['type'],
|
||||
'tmp_name' => $_FILES['files']['tmp_name'],
|
||||
'error' => $_FILES['files']['error'],
|
||||
'size' => $_FILES['files']['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$res = attach_store(App::get_channel(), get_observer_hash(), '', ['album' => t('Profile Photos'), 'hash' => $hash, 'nosync' => true, 'source' => 'photos']);
|
||||
|
||||
json_return_and_die(['message' => $hash]);
|
||||
|
||||
}
|
||||
|
||||
if(($res && intval($res['data']['is_photo'])) || $importing) {
|
||||
if (($res && intval($res['data']['is_photo'])) || $importing) {
|
||||
$i = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale",
|
||||
dbesc($hash),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if(! $i) {
|
||||
notice( t('Image upload failed.') . EOL );
|
||||
if (!$i) {
|
||||
notice(t('Image upload failed.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$os_storage = false;
|
||||
|
||||
foreach($i as $ii) {
|
||||
if(intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
foreach ($i as $ii) {
|
||||
if (intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
$os_storage = intval($ii['os_storage']);
|
||||
$imagedata = $ii['content'];
|
||||
$filetype = $ii['mimetype'];
|
||||
$imagedata = $ii['content'];
|
||||
$filetype = $ii['mimetype'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$imagedata = (($os_storage) ? @file_get_contents(dbunescbin($imagedata)) : dbunescbin($imagedata));
|
||||
$ph = photo_factory($imagedata, $filetype);
|
||||
$ph = photo_factory($imagedata, $filetype);
|
||||
|
||||
if(! $ph->is_valid()) {
|
||||
notice( t('Unable to process image.') . EOL );
|
||||
if (!$ph->is_valid()) {
|
||||
notice(t('Unable to process image.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
return $this->profile_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
|
||||
// This will "fall through" to the get() method, and since
|
||||
// App::$data['imagecrop'] is set, it will proceed to cropping
|
||||
@@ -322,101 +380,108 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
/* @brief Generate content of profile-photo view
|
||||
*
|
||||
* @param $a Current application
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
if (!local_channel()) {
|
||||
notice(t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$pf = 0;
|
||||
$newuser = false;
|
||||
$channel = App::get_channel();
|
||||
$profile_id = (($_REQUEST['profile']) ? intval($_REQUEST['profile']) : intval(argv(1)));
|
||||
$default_profile_id = null;
|
||||
|
||||
if(argc() == 2 && argv(1) === 'new')
|
||||
$newuser = true;
|
||||
$r = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if(argv(1) === 'use') {
|
||||
|
||||
foreach ($r as $rr) {
|
||||
if ($rr['is_default']) {
|
||||
$default_profile_id = intval($rr['id']);
|
||||
}
|
||||
|
||||
if ($profile_id === intval($rr['id'])) {
|
||||
$profile = $rr;
|
||||
}
|
||||
}
|
||||
|
||||
$is_default_profile = ($profile_id === $default_profile_id);
|
||||
|
||||
if (argv(1) === 'use') {
|
||||
if (argc() < 3) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
notice(t('Permission denied.') . EOL);
|
||||
return;
|
||||
};
|
||||
|
||||
$resource_id = argv(2);
|
||||
|
||||
|
||||
$pf = (($_REQUEST['pf']) ? intval($_REQUEST['pf']) : 0);
|
||||
|
||||
$c = q("select id, is_default from profile where uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$multi_profiles = true;
|
||||
|
||||
if(($c) && (count($c) === 1) && (intval($c[0]['is_default']))) {
|
||||
$_REQUEST['profile'] = $c[0]['id'];
|
||||
$multi_profiles = false;
|
||||
}
|
||||
else {
|
||||
$_REQUEST['profile'] = $pf;
|
||||
}
|
||||
|
||||
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
|
||||
intval(local_channel()),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if(! $r) {
|
||||
notice( t('Photo not available.') . EOL );
|
||||
if (!$r) {
|
||||
notice(t('Photo not available.') . EOL);
|
||||
return;
|
||||
}
|
||||
$havescale = false;
|
||||
foreach($r as $rr) {
|
||||
if($rr['imgscale'] == PHOTO_RES_PROFILE_80)
|
||||
foreach ($r as $rr) {
|
||||
if ($rr['imgscale'] == PHOTO_RES_PROFILE_80)
|
||||
$havescale = true;
|
||||
}
|
||||
|
||||
// set an already loaded and cropped photo as profile photo
|
||||
|
||||
if($havescale) {
|
||||
// unset any existing profile photos
|
||||
$x = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_PROFILE),
|
||||
if ($havescale) {
|
||||
|
||||
if ($is_default_profile) {
|
||||
|
||||
// unset any existing profile photos
|
||||
q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_PROFILE),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$edited = datetime_convert();
|
||||
|
||||
q("UPDATE photo SET photo_usage = %d, edited = '%s' WHERE uid = %d AND resource_id = '%s' AND imgscale > 0",
|
||||
intval(PHOTO_PROFILE),
|
||||
dbescdate($edited),
|
||||
intval(local_channel()),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
q("UPDATE xchan SET xchan_photo_date = '%s' WHERE xchan_hash = '%s'",
|
||||
dbescdate($edited),
|
||||
dbesc($channel['xchan_hash'])
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d",
|
||||
dbesc(z_root() . '/photo/' . $resource_id . '-4'),
|
||||
dbesc(z_root() . '/photo/' . $resource_id . '-5'),
|
||||
intval($profile_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
$edited = datetime_convert();
|
||||
photo_profile_setperms(local_channel(), $resource_id, $profile_id);
|
||||
|
||||
$x = q("UPDATE photo SET photo_usage = %d, edited = '%s' WHERE uid = %d AND resource_id = '%s' AND imgscale > 0",
|
||||
intval(PHOTO_PROFILE),
|
||||
dbescdate($edited),
|
||||
intval(local_channel()),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
$x = q("UPDATE xchan SET xchan_photo_date = '%s' WHERE xchan_hash = '%s'",
|
||||
dbescdate($edited),
|
||||
dbesc($channel['xchan_hash'])
|
||||
);
|
||||
|
||||
photo_profile_setperms(local_channel(),$resource_id,$_REQUEST['profile']);
|
||||
|
||||
$sync = attach_export_data($channel,$resource_id);
|
||||
if($sync)
|
||||
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
$sync = attach_export_data($channel, $resource_id);
|
||||
if ($sync)
|
||||
Libsync::build_sync_packet($channel['channel_id'], ['file' => [$sync]]);
|
||||
|
||||
$_SESSION['reload_avatar'] = true;
|
||||
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
|
||||
Master::Summon(['Directory', local_channel()]);
|
||||
|
||||
goaway(z_root() . '/profiles');
|
||||
goaway(z_root() . '/profiles/' . $profile_id);
|
||||
}
|
||||
|
||||
$r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
|
||||
@@ -424,94 +489,74 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
intval(local_channel())
|
||||
|
||||
);
|
||||
if(! $r) {
|
||||
notice( t('Photo not available.') . EOL );
|
||||
if (!$r) {
|
||||
notice(t('Photo not available.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(intval($r[0]['os_storage']))
|
||||
if (intval($r[0]['os_storage'])) {
|
||||
$data = @file_get_contents(dbunescbin($r[0]['content']));
|
||||
else
|
||||
}
|
||||
else {
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
}
|
||||
|
||||
$ph = photo_factory($data, $r[0]['mimetype']);
|
||||
$ph = photo_factory($data, $r[0]['mimetype']);
|
||||
$smallest = 0;
|
||||
if($ph->is_valid()) {
|
||||
|
||||
if ($ph->is_valid()) {
|
||||
|
||||
// go ahead as if we have just uploaded a new photo to crop
|
||||
$i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale",
|
||||
dbesc($r[0]['resource_id']),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($i) {
|
||||
if ($i) {
|
||||
$hash = $i[0]['resource_id'];
|
||||
foreach($i as $ii) {
|
||||
if(intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||
foreach ($i as $ii) {
|
||||
if (intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($multi_profiles) {
|
||||
\App::$data['importfile'] = $resource_id;
|
||||
}
|
||||
else {
|
||||
$this->profile_photo_crop_ui_head($a, $ph, $hash, $smallest);
|
||||
}
|
||||
$this->profile_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
|
||||
// falls through with App::$data['imagecrop'] set so we go straight to the cropping section
|
||||
|
||||
}
|
||||
|
||||
|
||||
// present an upload form
|
||||
$importing = ((array_key_exists('importfile', App::$data)) ? true : false);
|
||||
|
||||
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if($profiles) {
|
||||
for($x = 0; $x < count($profiles); $x ++) {
|
||||
$profiles[$x]['selected'] = false;
|
||||
if($pf && $profiles[$x]['id'] == $pf)
|
||||
$profiles[$x]['selected'] = true;
|
||||
if((! $pf) && $profiles[$x]['is_default'])
|
||||
$profiles[$x]['selected'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$importing = ((array_key_exists('importfile',\App::$data)) ? true : false);
|
||||
|
||||
if(! x(\App::$data,'imagecrop')) {
|
||||
if (!x(App::$data, 'imagecrop')) {
|
||||
|
||||
$tpl = get_markup_template('profile_photo.tpl');
|
||||
|
||||
$o .= replace_macros($tpl,array(
|
||||
'$user' => \App::$channel['channel_address'],
|
||||
'$info' => ((count($profiles) > 1) ? t('Your default profile photo is visible to anybody on the internet. Profile photos for alternate profiles will inherit the permissions of the profile') : t('Your profile photo is visible to anybody on the internet and may be distributed to other websites.')),
|
||||
'$importfile' => (($importing) ? \App::$data['importfile'] : ''),
|
||||
'$lbl_upfile' => t('Upload File:'),
|
||||
'$lbl_profiles' => t('Select a profile:'),
|
||||
'$title' => (($importing) ? t('Use Photo for Profile') : t('Change Profile Photo')),
|
||||
'$submit' => (($importing) ? t('Use') : t('Upload')),
|
||||
'$remove' => t('Remove'),
|
||||
'$profiles' => $profiles,
|
||||
'$single' => ((count($profiles) == 1) ? true : false),
|
||||
'$profile0' => $profiles[0],
|
||||
'$embedPhotos' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
|
||||
$o = replace_macros($tpl, [
|
||||
'$user' => App::$channel['channel_address'],
|
||||
'$info' => (($is_default_profile) ? t('This profile photo will be visible to anybody on the internet and may be distributed to other websites.') : t('This profile photo will be visible only to channels with permission to view this profile.')),
|
||||
'$importfile' => (($importing) ? App::$data['importfile'] : ''),
|
||||
'$title' => (($importing) ? t('Use Photo for Profile') : t('Change Profile Photo')),
|
||||
'$submit' => t('Upload'),
|
||||
'$remove' => t('Reset to default'),
|
||||
'$profile_id' => $profile_id,
|
||||
'$profile' => $profile,
|
||||
'$embedPhotos' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalCancel' => t('Cancel'),
|
||||
'$embedPhotosModalOK' => t('OK'),
|
||||
'$modalchooseimages' => t('Choose images to embed'),
|
||||
'$modalchoosealbum' => t('Choose an album'),
|
||||
'$modaldiffalbum' => t('Choose a different album'),
|
||||
'$modalerrorlist' => t('Error getting album list'),
|
||||
'$modalerrorlink' => t('Error getting photo link'),
|
||||
'$modalerroralbum' => t('Error getting album'),
|
||||
'$form_security_token' => get_form_security_token("profile_photo"),
|
||||
'$select' => t('Select existing photo'),
|
||||
));
|
||||
'$embedPhotosModalOK' => t('OK'),
|
||||
'$modalchooseimages' => t('Choose images to embed'),
|
||||
'$modalchoosealbum' => t('Choose an album'),
|
||||
'$modaldiffalbum' => t('Choose a different album'),
|
||||
'$modalerrorlist' => t('Error getting album list'),
|
||||
'$modalerrorlink' => t('Error getting photo link'),
|
||||
'$modalerroralbum' => t('Error getting album'),
|
||||
'$form_security_token' => get_form_security_token("profile_photo"),
|
||||
'$select' => t('Select existing'),
|
||||
]);
|
||||
|
||||
call_hooks('profile_photo_content_end', $o);
|
||||
|
||||
@@ -521,19 +566,20 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
// present a cropping form
|
||||
|
||||
$filename = \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution'];
|
||||
$resolution = \App::$data['imagecrop_resolution'];
|
||||
$tpl = get_markup_template("cropbody.tpl");
|
||||
$o .= replace_macros($tpl,array(
|
||||
'$filename' => $filename,
|
||||
'$profile' => intval($_REQUEST['profile']),
|
||||
'$resource' => \App::$data['imagecrop'] . '-' . \App::$data['imagecrop_resolution'],
|
||||
'$image_url' => z_root() . '/photo/' . $filename,
|
||||
'$title' => t('Crop Image'),
|
||||
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
|
||||
$filename = App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'];
|
||||
$tpl = get_markup_template("cropbody.tpl");
|
||||
|
||||
$o = replace_macros($tpl, [
|
||||
'$filename' => $filename,
|
||||
'$profile' => $profile_id,
|
||||
'$resource' => App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'],
|
||||
'$image_url' => z_root() . '/photo/' . $filename,
|
||||
'$title' => t('Crop Image'),
|
||||
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
|
||||
'$form_security_token' => get_form_security_token("profile_photo"),
|
||||
'$done' => t('Done Editing')
|
||||
));
|
||||
'$done' => t('Done editing')
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
@@ -542,35 +588,37 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
||||
|
||||
/* @brief Generate the UI for photo-cropping
|
||||
*
|
||||
* @param $a Current application
|
||||
* @param $ph Photo-Factory
|
||||
* @return void
|
||||
* @param $ph
|
||||
* @param $hash
|
||||
* @param $smallest
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function profile_photo_crop_ui_head($ph, $hash, $smallest) {
|
||||
|
||||
function profile_photo_crop_ui_head(&$a, $ph, $hash, $smallest){
|
||||
$max_length = get_config('system', 'max_image_length');
|
||||
|
||||
$max_length = get_config('system','max_image_length');
|
||||
if(! $max_length)
|
||||
if (!$max_length) {
|
||||
$max_length = MAX_IMAGE_LENGTH;
|
||||
if($max_length > 0)
|
||||
}
|
||||
if ($max_length > 0) {
|
||||
$ph->scaleImage($max_length);
|
||||
|
||||
\App::$data['width'] = $ph->getWidth();
|
||||
\App::$data['height'] = $ph->getHeight();
|
||||
|
||||
if(\App::$data['width'] < 500 || \App::$data['height'] < 500) {
|
||||
$ph->scaleImageUp(400);
|
||||
\App::$data['width'] = $ph->getWidth();
|
||||
\App::$data['height'] = $ph->getHeight();
|
||||
}
|
||||
|
||||
App::$data['width'] = $ph->getWidth();
|
||||
App::$data['height'] = $ph->getHeight();
|
||||
|
||||
if (App::$data['width'] < 500 || App::$data['height'] < 500) {
|
||||
$ph->scaleImageUp(400);
|
||||
App::$data['width'] = $ph->getWidth();
|
||||
App::$data['height'] = $ph->getHeight();
|
||||
}
|
||||
|
||||
App::$data['imagecrop'] = $hash;
|
||||
App::$data['imagecrop_resolution'] = $smallest;
|
||||
App::$page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), []);
|
||||
|
||||
\App::$data['imagecrop'] = $hash;
|
||||
\App::$data['imagecrop_resolution'] = $smallest;
|
||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template("crophead.tpl"), array());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -163,34 +163,6 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Run profile_load() here to make sure the theme is set before
|
||||
// we start loading content
|
||||
if(((argc() > 1) && (intval(argv(1)))) || !feature_enabled(local_channel(),'multi_profiles')) {
|
||||
if(feature_enabled(local_channel(),'multi_profiles'))
|
||||
$id = \App::$argv[1];
|
||||
else {
|
||||
$x = q("select id from profile where uid = %d and is_default = 1",
|
||||
intval(local_channel())
|
||||
);
|
||||
if($x)
|
||||
$id = $x[0]['id'];
|
||||
}
|
||||
$r = q("SELECT * FROM profile WHERE id = %d AND uid = %d LIMIT 1",
|
||||
intval($id),
|
||||
intval(local_channel())
|
||||
);
|
||||
if(! count($r)) {
|
||||
notice( t('Profile not found.') . EOL);
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
$chan = \App::get_channel();
|
||||
profile_load($chan['channel_address'],$r[0]['id']);
|
||||
}
|
||||
}
|
||||
|
||||
function post() {
|
||||
@@ -316,8 +288,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 +483,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 +531,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 +568,7 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
dbesc($education),
|
||||
intval($hide_friends),
|
||||
dbesc($profile_vcard),
|
||||
intval($publish),
|
||||
intval(argv(1)),
|
||||
intval(local_channel())
|
||||
);
|
||||
@@ -597,10 +579,11 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
$channel = \App::get_channel();
|
||||
|
||||
if($namechanged && $is_default) {
|
||||
q("UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_hash = '%s'",
|
||||
// change name on all associated xchans by matching the url
|
||||
q("UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_url = '%s'",
|
||||
dbesc($name),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($channel['xchan_hash'])
|
||||
dbesc(z_root() . '/channel/' . $channel['channel_address'])
|
||||
);
|
||||
q("UPDATE channel SET channel_name = '%s' WHERE channel_hash = '%s'",
|
||||
dbesc($name),
|
||||
@@ -618,8 +601,6 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
if($is_default) {
|
||||
// reload the info for the sidebar widget
|
||||
profile_load($channel['channel_address']);
|
||||
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
|
||||
}
|
||||
}
|
||||
@@ -630,13 +611,13 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
|
||||
$o = '';
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
if(! local_channel()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
require_once('include/channel.php');
|
||||
|
||||
$profile_fields_basic = get_profile_fields_basic();
|
||||
@@ -652,6 +633,7 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
if($x)
|
||||
$id = $x[0]['id'];
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM profile WHERE id = %d AND uid = %d LIMIT 1",
|
||||
intval($id),
|
||||
intval(local_channel())
|
||||
@@ -662,6 +644,9 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure we got uptodate data
|
||||
profile_load($channel['channel_address'], $id);
|
||||
|
||||
$editselect = 'none';
|
||||
|
||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template('profed_head.tpl'), array(
|
||||
@@ -675,13 +660,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 = '<input type="hidden" name="profile_in_directory" value="1" />';
|
||||
}
|
||||
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) {
|
||||
@@ -702,15 +717,15 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
|
||||
//logger('extra_fields: ' . print_r($extra_fields,true));
|
||||
|
||||
$vc = $r[0]['profile_vcard'];
|
||||
$vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
|
||||
$vcard = (($vctmp) ? get_vcard_array($vctmp,$r[0]['id']) : [] );
|
||||
//$vc = $r[0]['profile_vcard'];
|
||||
//$vctmp = (($vc) ? \Sabre\VObject\Reader::read($vc) : null);
|
||||
//$vcard = (($vctmp) ? get_vcard_array($vctmp,$r[0]['id']) : [] );
|
||||
|
||||
$f = get_config('system','birthday_input_format');
|
||||
if(! $f)
|
||||
$f = 'ymd';
|
||||
|
||||
$is_default = (($r[0]['is_default']) ? 1 : 0);
|
||||
|
||||
|
||||
$tpl = get_markup_template("profile_edit.tpl");
|
||||
$o .= replace_macros($tpl,array(
|
||||
@@ -719,12 +734,12 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
'$profile_clone_link' => 'profiles/clone/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_clone"),
|
||||
'$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_drop"),
|
||||
'$fields' => $fields,
|
||||
'$vcard' => $vcard,
|
||||
//'$vcard' => $vcard,
|
||||
'$guid' => $r[0]['profile_guid'],
|
||||
'$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 +747,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'),
|
||||
@@ -784,23 +799,28 @@ class Profiles extends \Zotlabs\Web\Controller {
|
||||
'$contact' => array('contact', t('Contact information and social networks'), $r[0]['contact']),
|
||||
'$channels' => array('channels', t('My other channels'), $r[0]['channels']),
|
||||
'$extra_fields' => $extra_fields,
|
||||
'$comms' => t('Communications'),
|
||||
'$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'),
|
||||
//'$comms' => t('Communications'),
|
||||
//'$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'),
|
||||
|
||||
'$show_presence' => $show_presence,
|
||||
'$suggestme' => $suggestme,
|
||||
'$profile_in_dir' => $profile_in_dir,
|
||||
|
||||
));
|
||||
|
||||
$arr = array('profile' => $r[0], 'entry' => $o);
|
||||
|
||||
@@ -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']]);
|
||||
|
||||
@@ -57,8 +57,8 @@ class Removeme extends \Zotlabs\Web\Controller {
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$basedir' => z_root(),
|
||||
'$hash' => $hash,
|
||||
'$title' => t('Remove This Channel'),
|
||||
'$desc' => [ t('WARNING: '), t('This channel will be completely removed from the network. '), t('This action is permanent and can not be undone!') ],
|
||||
'$title' => t('Remove Channel'),
|
||||
'$desc' => [ t('WARNING: '), t('This channel will be permanently removed. '), t('This action can not be undone!') ],
|
||||
'$passwd' => t('Please enter your password for verification:'),
|
||||
// '$global' => [ 'global', t('Remove this channel and all its clones from the network'), false, t('By default only the instance of the channel located on this hub will be removed from the network'), [ t('No'),t('Yes') ] ],
|
||||
'$submit' => t('Remove Channel')
|
||||
|
||||
@@ -7,6 +7,7 @@ use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\ActivityStreams;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Zotfinger;
|
||||
|
||||
class Search extends Controller {
|
||||
|
||||
@@ -58,10 +59,26 @@ class Search extends Controller {
|
||||
$o .= search($search, 'search-box', '/search', ((local_channel()) ? true : false));
|
||||
|
||||
if (local_channel() && strpos($search, 'https://') === 0 && !$update && !$load) {
|
||||
if (strpos($search, 'b64.') !== false) {
|
||||
if (strpos($search, '?') !== false) {
|
||||
$search = strtok($search, '?');
|
||||
}
|
||||
|
||||
$search = unpack_link_id(basename($search));
|
||||
}
|
||||
|
||||
$f = Libzot::fetch_conversation(App::get_channel(), punify($search), true);
|
||||
|
||||
if ($f) {
|
||||
goaway(z_root() . '/hq/' . gen_link_id($f['message_id']));
|
||||
$mid = $f[0]['message_id'];
|
||||
foreach ($f as $m) {
|
||||
if (strpos($search, $m['message_id']) === 0) {
|
||||
$mid = $m['message_id'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
goaway(z_root() . '/hq/' . gen_link_id($mid));
|
||||
}
|
||||
else {
|
||||
// try other fetch providers (e.g. diaspora, pubcrawl)
|
||||
|
||||
@@ -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,272 @@ 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 = '';
|
||||
$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);
|
||||
|
||||
$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)
|
||||
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 = '';
|
||||
|
||||
$name_change = false;
|
||||
|
||||
if($username != $channel['channel_name']) {
|
||||
$name_change = true;
|
||||
require_once('include/channel.php');
|
||||
$err = validate_channelname($username);
|
||||
if($err) {
|
||||
notice($err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if($timezone != $channel['channel_timezone']) {
|
||||
if(strlen($timezone))
|
||||
if ($timezone !== $channel['channel_timezone']) {
|
||||
if (strlen($timezone))
|
||||
date_default_timezone_set($timezone);
|
||||
}
|
||||
|
||||
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);
|
||||
if (!$role) {
|
||||
notice(t('Please select a channel role') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$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),
|
||||
if ($role !== get_pconfig(local_channel(), 'system', 'permissions_role')) {
|
||||
$role_permissions = PermissionRoles::role_perms($_POST['permissions_role']);
|
||||
|
||||
if (isset($role_permissions['limits'])) {
|
||||
foreach ($role_permissions['limits'] as $k => $v) {
|
||||
PermissionLimits::Set(local_channel(), $k, $v);
|
||||
}
|
||||
}
|
||||
|
||||
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', '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');
|
||||
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())) ? '<br />' . 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;
|
||||
|
||||
$yes_no = array(t('No'),t('Yes'));
|
||||
$expire = $channel['channel_expire_days'];
|
||||
$sys_expire = get_config('system', 'default_expire_days');
|
||||
|
||||
|
||||
$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 = '<input type="hidden" name="profile_in_directory" value="1" />';
|
||||
}
|
||||
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())) ? '<br />' . 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'),
|
||||
$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()
|
||||
));
|
||||
'$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)
|
||||
$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';
|
||||
|
||||
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 = '<input type="hidden" name="autoperms" value="' . intval(get_pconfig(local_channel(),'system','autoperms')) . '" />';
|
||||
|
||||
$permissions_set = (($permissions_role != 'custom') ? true : false);
|
||||
|
||||
$perm_roles = \Zotlabs\Access\PermissionRoles::roles();
|
||||
|
||||
$always_show_in_notices = get_pconfig(local_channel(),'system','always_show_in_notices');
|
||||
$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');
|
||||
|
||||
if($vnotify === false)
|
||||
$vnotify = get_pconfig(local_channel(), 'system', 'vnotify');
|
||||
if ($vnotify === false)
|
||||
$vnotify = (-1);
|
||||
|
||||
$plugin = [ 'basic' => '', 'security' => '', 'notify' => '' ];
|
||||
call_hooks('channel_settings',$plugin);
|
||||
$perm_roles = PermissionRoles::channel_roles();
|
||||
$permissions_role = get_pconfig(local_channel(), 'system', 'permissions_role');
|
||||
|
||||
$disable_discover_tab = intval(get_config('system','disable_discover_tab',1)) == 1;
|
||||
$site_firehose = intval(get_config('system','site_firehose',0)) == 1;
|
||||
if (!in_array($permissions_role, ['public', 'personal', 'group', 'custom'])) {
|
||||
notice(t('Please select a channel role') . EOL);
|
||||
array_unshift($perm_roles , '');
|
||||
}
|
||||
|
||||
$plugin = ['basic' => '', 'notify' => ''];
|
||||
call_hooks('channel_settings', $plugin);
|
||||
|
||||
$o .= replace_macros($stpl,array(
|
||||
'$ptitle' => t('Channel Settings'),
|
||||
$yes_no = [t('No'), t('Yes')];
|
||||
|
||||
'$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 - <em>extremely permissive (should be used with caution)</em>'),
|
||||
'$pmacro2' => t('Typical - <em>default public, privacy when desired (similar to social network permissions but with improved privacy)</em>'),
|
||||
'$pmacro1' => t('Private - <em>default private, never open or public</em>'),
|
||||
'$pmacro0' => t('Blocked - <em>default blocked to/from everybody</em>'),
|
||||
'$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 <em>interesting</em> 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'), $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:'),
|
||||
'$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 <em>interesting</em> 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'],
|
||||
'$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.')],
|
||||
]);
|
||||
|
||||
'$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 .= '</form>' . "\r\n";
|
||||
call_hooks('settings_form', $o);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
127
Zotlabs/Module/Settings/Privacy.php
Normal file
127
Zotlabs/Module/Settings/Privacy.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module\Settings;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
use Zotlabs\Access\Permissions;
|
||||
use Zotlabs\Daemon\Master;
|
||||
use Zotlabs\Lib\Group;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
|
||||
class Privacy {
|
||||
|
||||
function post() {
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/privacy', 'settings');
|
||||
call_hooks('settings_post', $_POST);
|
||||
|
||||
$index_opt_out = (((x($_POST, 'index_opt_out')) && (intval($_POST['index_opt_out']) == 1)) ? 1 : 0);
|
||||
set_pconfig(local_channel(), 'system', 'index_opt_out', $index_opt_out);
|
||||
|
||||
$autoperms = (((x($_POST, 'autoperms')) && (intval($_POST['autoperms']) == 1)) ? 1 : 0);
|
||||
set_pconfig(local_channel(), 'system', 'autoperms', $autoperms);
|
||||
|
||||
$role = get_pconfig(local_channel(), 'system', 'permissions_role');
|
||||
if ($role === 'custom') {
|
||||
|
||||
$global_perms = Permissions::Perms();
|
||||
|
||||
foreach ($global_perms as $k => $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;
|
||||
}
|
||||
}
|
||||
@@ -13,14 +13,14 @@ class Profiles {
|
||||
$module = substr(strrchr(strtolower(static::class), '\\'), 1);
|
||||
|
||||
check_form_security_token_redirectOnErr('/settings/' . $module, 'settings_' . $module);
|
||||
|
||||
|
||||
$features = get_module_features($module);
|
||||
|
||||
process_module_features_post(local_channel(), $features, $_POST);
|
||||
|
||||
$profile_assign = ((x($_POST,'profile_assign')) ? notags(trim($_POST['profile_assign'])) : '');
|
||||
set_pconfig(local_channel(),'system','profile_assign',$profile_assign);
|
||||
|
||||
|
||||
Libsync::build_sync_packet();
|
||||
|
||||
if($_POST['rpath'])
|
||||
@@ -38,7 +38,7 @@ class Profiles {
|
||||
|
||||
$extra_settings_html = '';
|
||||
if(feature_enabled(local_channel(),'multi_profiles'))
|
||||
$extra_settings_html = contact_profile_assign(get_pconfig(local_channel(),'system','profile_assign',''));
|
||||
$extra_settings_html = contact_profile_assign(get_pconfig(local_channel(),'system','profile_assign',''), t('Default profile for new contacts'));
|
||||
|
||||
$tpl = get_markup_template("settings_module.tpl");
|
||||
|
||||
@@ -51,7 +51,7 @@ class Profiles {
|
||||
'$extra_settings_html' => $extra_settings_html,
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,17 +69,22 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
|
||||
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
|
||||
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
|
||||
|
||||
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
|
||||
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
|
||||
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($db_type) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
// $siteurl should not have a trailing slash
|
||||
|
||||
$siteurl = rtrim($siteurl,'/');
|
||||
|
||||
require_once('include/dba/dba_driver.php');
|
||||
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, $db_charset, true);
|
||||
|
||||
if(! \DBA::$dba->connected) {
|
||||
echo 'Database Connect failed: ' . \DBA::$dba->error;
|
||||
@@ -94,11 +99,16 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
$dbpass = ((isset($_POST['dbpass'])) ? trim($_POST['dbpass']) : '');
|
||||
$dbdata = ((isset($_POST['dbdata'])) ? trim($_POST['dbdata']) : '');
|
||||
$dbtype = ((isset($_POST['dbtype'])) ? intval(trim($_POST['dbtype'])) : 0);
|
||||
|
||||
$phpath = ((isset($_POST['phpath'])) ? trim($_POST['phpath']) : '');
|
||||
$timezone = ((isset($_POST['timezone'])) ? trim($_POST['timezone']) : '');
|
||||
$adminmail = ((isset($_POST['adminmail'])) ? trim($_POST['adminmail']) : '');
|
||||
$siteurl = ((isset($_POST['siteurl'])) ? trim($_POST['siteurl']) : '');
|
||||
|
||||
if (empty($db_charset)) {
|
||||
$db_charset = ((intval($db_type) === 0) ? 'utf8mb4' : 'UTF8');
|
||||
}
|
||||
|
||||
if($siteurl != z_root()) {
|
||||
$test = z_fetch_url($siteurl."/setup/testrewrite");
|
||||
if((! $test['success']) || ($test['body'] != 'ok')) {
|
||||
@@ -112,7 +122,7 @@ class Setup extends \Zotlabs\Web\Controller {
|
||||
|
||||
if(! isset(\DBA::$dba->connected)) {
|
||||
// connect to db
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
|
||||
$db = \DBA::dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, $db_charset, true);
|
||||
}
|
||||
|
||||
if(! isset(\DBA::$dba->connected)) {
|
||||
|
||||
@@ -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,65 @@ 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');
|
||||
|
||||
if(isset($_POST['delete'])) {
|
||||
$r = q("select * from atoken where atoken_id = %d and atoken_uid = %d",
|
||||
intval($_POST['atoken_id']),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if (!$r) {
|
||||
return;
|
||||
}
|
||||
|
||||
$atoken = $r[0];
|
||||
$atoken_xchan = substr($channel['channel_hash'], 0, 16) . '.' . $atoken['atoken_guid'];
|
||||
|
||||
$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['channel_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($atoken['atoken_id']);
|
||||
Libsync::build_sync_packet($channel['channel_id'], [ 'abook' => [ $clone ], 'atoken' => [ $atoken ] ], true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$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 +85,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 +100,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 +122,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 +133,84 @@ 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($channel['channel_id'], 'system', 'new_abook_closeness',80);
|
||||
$profile_assign = get_pconfig($channel['channel_id'], '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($channel['channel_id'], $channel['channel_default_group']);
|
||||
if ($g) {
|
||||
AccessList::member_add($channel['channel_id'], '', $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;
|
||||
@@ -99,10 +229,13 @@ class Tokens extends Controller {
|
||||
return Apps::app_render($papp, 'module');
|
||||
}
|
||||
|
||||
nav_set_selected('Guest Access');
|
||||
|
||||
$channel = App::get_channel();
|
||||
|
||||
$atoken = null;
|
||||
$atoken_xchan = '';
|
||||
$atoken_abook = [];
|
||||
|
||||
if(argc() > 1) {
|
||||
$id = argv(1);
|
||||
@@ -114,76 +247,52 @@ 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'];
|
||||
|
||||
if($atoken && argc() > 2 && argv(2) === 'drop') {
|
||||
atoken_delete($id);
|
||||
$atoken = null;
|
||||
$atoken_xchan = '';
|
||||
$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];
|
||||
}
|
||||
}
|
||||
|
||||
$t = q("select * from atoken where atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
$desc = t('Use this form to create temporary access identifiers to share things with non-members. These identities may be used in privacy groups and visitors may login using these credentials to access private content.');
|
||||
|
||||
$desc = t('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.');
|
||||
$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);
|
||||
|
||||
$desc2 = t('You may also provide <em>dropbox</em> style access links to friends and associates by adding the Login Password to any specific site URL as shown. Examples:');
|
||||
$roles_dict = [];
|
||||
foreach ($pcatlist as $role) {
|
||||
$roles_dict[$role['name']] = $role['localname'];
|
||||
}
|
||||
|
||||
$global_perms = \Zotlabs\Access\Permissions::Perms();
|
||||
$their_perms = [];
|
||||
if (!$current_permcat) {
|
||||
notice(t('Please select a role for this guest!') . EOL);
|
||||
$permcats[] = '';
|
||||
}
|
||||
|
||||
$existing = get_all_perms(local_channel(),(($atoken_xchan) ? $atoken_xchan : ''),false);
|
||||
|
||||
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'];
|
||||
}
|
||||
if ($pcatlist) {
|
||||
foreach ($pcatlist as $pc) {
|
||||
$permcats[$pc['name']] = $pc['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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$tpl = get_markup_template("tokens.tpl");
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$form_security_token' => get_form_security_token("tokens"),
|
||||
'$title' => t('Guest Access Tokens'),
|
||||
'$desc' => $desc,
|
||||
'$desc2' => $desc2,
|
||||
'$tokens' => $t,
|
||||
'$form_security_token' => get_form_security_token('tokens'),
|
||||
'$permcat' => ['permcat', t('Select a role for this guest'), $current_permcat, '', $permcats],
|
||||
'$title' => t('Guest Access'),
|
||||
'$desc' => $desc,
|
||||
'$atoken' => $atoken,
|
||||
'$url1' => z_root() . '/channel/' . $channel['channel_address'],
|
||||
'$url2' => z_root() . '/photos/' . $channel['channel_address'],
|
||||
'$name' => array('name', t('Login Name') . ' <span class="required">*</span>', (($atoken) ? $atoken['atoken_name'] : ''),''),
|
||||
'$token'=> array('token', t('Login Password') . ' <span class="required">*</span>',(($atoken) ? $atoken['atoken_token'] : autoname(8)), ''),
|
||||
'$token'=> array('token', t('Login Password') . ' <span class="required">*</span>',(($atoken) ? $atoken['atoken_token'] : new_token()), ''),
|
||||
'$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 <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here.'),
|
||||
'$submit' => t('Submit')
|
||||
'$submit' => t('Submit'),
|
||||
'$delete' => t('Delete')
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
@@ -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 = '';
|
||||
|
||||
@@ -6,7 +6,7 @@ require_once('include/selectors.php');
|
||||
class Viewconnections extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
if(observer_prohibited()) {
|
||||
return;
|
||||
}
|
||||
@@ -16,58 +16,58 @@ class Viewconnections extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
|
||||
if(observer_prohibited()) {
|
||||
notice( t('Public access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(((! count(\App::$profile)) || (\App::$profile['hide_friends']))) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(! perm_is_allowed(\App::$profile['uid'], get_observer_hash(),'view_contacts')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(! $_REQUEST['aj'])
|
||||
$_SESSION['return_url'] = \App::$query_string;
|
||||
|
||||
|
||||
|
||||
|
||||
$is_owner = ((local_channel() && local_channel() == \App::$profile['uid']) ? true : false);
|
||||
|
||||
$abook_flags = " and abook_pending = 0 and abook_self = 0 ";
|
||||
|
||||
$abook_flags = " and abook_pending = 0 and abook_self = 0 and abook_blocked = 0 and abook_ignored = 0 ";
|
||||
$sql_extra = '';
|
||||
|
||||
|
||||
if(! $is_owner) {
|
||||
$abook_flags .= " and abook_hidden = 0 ";
|
||||
$sql_extra = " and xchan_hidden = 0 ";
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT count(*) as total FROM abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d $abook_flags and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra ",
|
||||
intval(\App::$profile['uid'])
|
||||
);
|
||||
if($r) {
|
||||
\App::set_pager_total($r[0]['total']);
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d $abook_flags and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra order by xchan_name LIMIT %d OFFSET %d ",
|
||||
intval(\App::$profile['uid']),
|
||||
intval(\App::$pager['itemspage']),
|
||||
intval(\App::$pager['start'])
|
||||
);
|
||||
|
||||
|
||||
if((! $r) && (! $_REQUEST['aj'])) {
|
||||
info( t('No connections.') . EOL );
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
$contacts = array();
|
||||
|
||||
|
||||
foreach($r as $rr) {
|
||||
|
||||
$oneway = false;
|
||||
@@ -103,7 +103,7 @@ class Viewconnections extends \Zotlabs\Web\Controller {
|
||||
'id' => $rr['abook_id'],
|
||||
'archived' => (intval($rr['abook_archived']) ? true : false),
|
||||
'img_hover' => sprintf( t('Visit %s\'s profile [%s]'), $rr['xchan_name'], $rr['xchan_url']),
|
||||
'thumb' => $rr['xchan_photo_m'],
|
||||
'thumb' => $rr['xchan_photo_m'],
|
||||
'name' => substr($rr['xchan_name'],0,20),
|
||||
'username' => $rr['xchan_addr'],
|
||||
'link' => $url,
|
||||
@@ -137,11 +137,11 @@ class Viewconnections extends \Zotlabs\Web\Controller {
|
||||
// '$paginate' => paginate($a),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
if(! $contacts)
|
||||
$o .= '<div id="content-complete"></div>';
|
||||
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -126,7 +126,7 @@ class Wfinger extends \Zotlabs\Web\Controller {
|
||||
'http://webfinger.net/ns/name' => $r['channel_name'],
|
||||
'http://xmlns.com/foaf/0.1/name' => $r['channel_name'],
|
||||
'https://w3id.org/security/v1#publicKeyPem' => $r['xchan_pubkey'],
|
||||
'http://purl.org/zot/federation' => 'zot6,zot'
|
||||
'http://purl.org/zot/federation' => 'zot6'
|
||||
];
|
||||
|
||||
foreach($aliases as $alias)
|
||||
@@ -183,12 +183,6 @@ class Wfinger extends \Zotlabs\Web\Controller {
|
||||
'href' => z_root() . '/profile/' . $r['channel_address'],
|
||||
],
|
||||
|
||||
[
|
||||
'rel' => 'http://schemas.google.com/g/2010#updates-from',
|
||||
'type' => 'application/atom+xml',
|
||||
'href' => z_root() . '/ofeed/' . $r['channel_address']
|
||||
],
|
||||
|
||||
[
|
||||
'rel' => 'http://webfinger.net/rel/blog',
|
||||
'href' => z_root() . '/channel/' . $r['channel_address'],
|
||||
@@ -205,11 +199,6 @@ class Wfinger extends \Zotlabs\Web\Controller {
|
||||
'href' => channel_url($r)
|
||||
],
|
||||
|
||||
[
|
||||
'rel' => 'http://purl.org/zot/protocol',
|
||||
'href' => z_root() . '/.well-known/zot-info' . '?address=' . $r['xchan_addr'],
|
||||
],
|
||||
|
||||
[
|
||||
'rel' => 'http://purl.org/openwebauth/v1',
|
||||
'type' => 'application/x-zot+json',
|
||||
|
||||
@@ -572,7 +572,7 @@ class Comanche {
|
||||
require_once('widget/' . trim($name) . '.php');
|
||||
elseif(file_exists('widget/' . trim($name) . '/' . trim($name) . '.php'))
|
||||
require_once('widget/' . trim($name) . '/' . trim($name) . '.php');
|
||||
|
||||
|
||||
if(! function_exists($func)) {
|
||||
$theme_widget = $func . '.php';
|
||||
if(theme_include($theme_widget)) {
|
||||
@@ -640,7 +640,8 @@ class Comanche {
|
||||
$cnt = preg_match_all("/\[widget=(.*?)\](.*?)\[\/widget\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$s = str_replace($mtch[0],$this->widget(trim($mtch[1]),$mtch[2]),$s);
|
||||
|
||||
$s = str_replace((string)$mtch[0], (string)$this->widget(trim((string)$mtch[1]), (string)$mtch[2]), $s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,14 +60,16 @@ class Theme {
|
||||
|
||||
// Allow theme selection of the form 'theme_name:schema_name'
|
||||
$themepair = explode(':', $chosen_theme);
|
||||
|
||||
// Check if $chosen_theme is compatible with core. If not fall back to default
|
||||
$info = get_theme_info($themepair[0]);
|
||||
|
||||
$compatible = check_plugin_versions($info);
|
||||
if(!$compatible) {
|
||||
$chosen_theme = '';
|
||||
}
|
||||
|
||||
App::$theme_info = $info;
|
||||
|
||||
if($chosen_theme && (file_exists('view/theme/' . $themepair[0] . '/css/style.css') || file_exists('view/theme/' . $themepair[0] . '/php/style.php'))) {
|
||||
return($themepair);
|
||||
}
|
||||
|
||||
31
Zotlabs/Update/_1249.php
Normal file
31
Zotlabs/Update/_1249.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Update;
|
||||
|
||||
class _1249 {
|
||||
|
||||
function run() {
|
||||
|
||||
dbq("START TRANSACTION");
|
||||
|
||||
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
||||
$r1 = dbq("ALTER TABLE abook ADD abook_role TEXT NOT NULL DEFAULT ''");
|
||||
$r2 = dbq("CREATE INDEX \"abook_role\" ON abook (\"abook_role\")");
|
||||
$r = ($r1 && $r2);
|
||||
}
|
||||
else {
|
||||
$r = dbq("ALTER TABLE `abook` ADD `abook_role` CHAR(191) NOT NULL DEFAULT '' ,
|
||||
ADD INDEX `abook_role` (`abook_role`)");
|
||||
}
|
||||
|
||||
if($r) {
|
||||
dbq("COMMIT");
|
||||
return UPDATE_SUCCESS;
|
||||
}
|
||||
|
||||
dbq("ROLLBACK");
|
||||
return UPDATE_FAILED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
31
Zotlabs/Update/_1250.php
Normal file
31
Zotlabs/Update/_1250.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Update;
|
||||
|
||||
class _1250 {
|
||||
|
||||
function run() {
|
||||
|
||||
dbq("START TRANSACTION");
|
||||
|
||||
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
|
||||
$r1 = dbq("ALTER TABLE atoken ADD atoken_guid VARCHAR(255) NOT NULL DEFAULT ''");
|
||||
$r2 = dbq("CREATE INDEX \"atoken_guid\" ON atoken (\"atoken_guid\")");
|
||||
$r = ($r1 && $r2);
|
||||
}
|
||||
else {
|
||||
$r = dbq("ALTER TABLE `atoken` ADD `atoken_guid` CHAR(191) NOT NULL DEFAULT '' ,
|
||||
ADD INDEX `atoken_guid` (`atoken_guid`)");
|
||||
}
|
||||
|
||||
if($r) {
|
||||
dbq("COMMIT");
|
||||
return UPDATE_SUCCESS;
|
||||
}
|
||||
|
||||
dbq("ROLLBACK");
|
||||
return UPDATE_FAILED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
23
Zotlabs/Update/_1251.php
Normal file
23
Zotlabs/Update/_1251.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Update;
|
||||
|
||||
class _1251 {
|
||||
|
||||
function run() {
|
||||
|
||||
dbq("START TRANSACTION");
|
||||
|
||||
$r = dbq("DELETE FROM app WHERE (app_name = 'Channel Home' OR app_name = 'Permission Categories') AND app_system = 1");
|
||||
|
||||
if($r) {
|
||||
dbq("COMMIT");
|
||||
return UPDATE_SUCCESS;
|
||||
}
|
||||
|
||||
dbq("ROLLBACK");
|
||||
return UPDATE_FAILED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
23
Zotlabs/Update/_1252.php
Normal file
23
Zotlabs/Update/_1252.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Update;
|
||||
|
||||
class _1252 {
|
||||
|
||||
function run() {
|
||||
|
||||
dbq("START TRANSACTION");
|
||||
|
||||
$r = dbq("DELETE FROM app WHERE app_plugin = 'mail' AND app_system = 1");
|
||||
|
||||
if($r) {
|
||||
dbq("COMMIT");
|
||||
return UPDATE_SUCCESS;
|
||||
}
|
||||
|
||||
dbq("ROLLBACK");
|
||||
return UPDATE_FAILED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -156,6 +156,7 @@ class HTTPSig {
|
||||
|
||||
$cached_key = self::get_key($key, $keytype, $result['signer']);
|
||||
|
||||
|
||||
if (!($cached_key && $cached_key['public_key'])) {
|
||||
return $result;
|
||||
}
|
||||
@@ -243,7 +244,12 @@ class HTTPSig {
|
||||
}
|
||||
}
|
||||
|
||||
$key = self::get_activitystreams_key($id, $force);
|
||||
$delete = false;
|
||||
if ($keytype === 'delete') {
|
||||
$delete = true;
|
||||
}
|
||||
|
||||
$key = self::get_activitystreams_key($id, $force, $delete);
|
||||
|
||||
return $key;
|
||||
|
||||
@@ -274,7 +280,7 @@ class HTTPSig {
|
||||
* false if no pub key found, otherwise return an array with the pub key
|
||||
*/
|
||||
|
||||
static function get_activitystreams_key($id, $force = false) {
|
||||
static function get_activitystreams_key($id, $force = false, $delete = false) {
|
||||
|
||||
// Check the local cache first, but remove any fragments like #main-key since these won't be present in our cached data
|
||||
$url = ((strpos($id, '#')) ? substr($id, 0, strpos($id, '#')) : $id);
|
||||
@@ -294,6 +300,12 @@ class HTTPSig {
|
||||
}
|
||||
}
|
||||
|
||||
if ($delete) {
|
||||
// If we received a delete and we do not have the record cached,
|
||||
// we probably never saw this actor. Do not try to fetch it now.
|
||||
return false;
|
||||
}
|
||||
|
||||
// The record wasn't in cache. Fetch it now.
|
||||
$r = ActivityStreams::fetch($id);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class Session {
|
||||
ini_set('session.cookie_httponly', 1);
|
||||
|
||||
$this->custom_handler = boolval(get_config('system', 'session_custom', false));
|
||||
|
||||
|
||||
/*
|
||||
* Set our session storage functions.
|
||||
*/
|
||||
@@ -67,23 +67,24 @@ class Session {
|
||||
}
|
||||
|
||||
|
||||
// Force cookies to be secure (https only) if this site is SSL enabled.
|
||||
// Force cookies to be secure (https only) if this site is SSL enabled.
|
||||
// Must be done before session_start().
|
||||
|
||||
|
||||
$arr = session_get_cookie_params();
|
||||
|
||||
|
||||
// Note when setting cookies: set the domain to false which creates a single domain
|
||||
// cookie. If you use a hostname it will create a .domain.com wildcard which will
|
||||
// have some nasty side effects if you have any other subdomains running hubzilla.
|
||||
// have some nasty side effects if you have any other subdomains running hubzilla.
|
||||
|
||||
session_set_cookie_params(
|
||||
((isset($arr['lifetime'])) ? $arr['lifetime'] : 0),
|
||||
((isset($arr['path'])) ? $arr['path'] : '/'),
|
||||
(($arr['domain']) ? $arr['domain'] : false),
|
||||
((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),
|
||||
((isset($arr['httponly'])) ? $arr['httponly'] : true)
|
||||
);
|
||||
session_set_cookie_params([
|
||||
'lifetime' => ((isset($arr['lifetime'])) ? $arr['lifetime'] : 0),
|
||||
'path' => ((isset($arr['path'])) ? $arr['path'] : '/'),
|
||||
'domain' => (($arr['domain']) ? $arr['domain'] : false),
|
||||
'secure' => ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),
|
||||
'httponly' => ((isset($arr['httponly'])) ? $arr['httponly'] : true),
|
||||
'samesite' => 'None'
|
||||
]);
|
||||
|
||||
register_shutdown_function('session_write_close');
|
||||
|
||||
@@ -127,13 +128,36 @@ class Session {
|
||||
$this->handler->read(session_id());
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
logger('no session handler');
|
||||
|
||||
if (x($_COOKIE, 'jsdisabled')) {
|
||||
setcookie('jsdisabled', $_COOKIE['jsdisabled'], $newxtime, '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true));
|
||||
setcookie(
|
||||
'jsdisabled',
|
||||
$_COOKIE['jsdisabled'],
|
||||
[
|
||||
'expires' => $newxtime,
|
||||
'path' => '/',
|
||||
'domain' => false,
|
||||
'secure' => ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),
|
||||
'httponly' => ((isset($arr['httponly'])) ? $arr['httponly'] : true),
|
||||
'samesite' => 'None'
|
||||
]
|
||||
);
|
||||
}
|
||||
setcookie(session_name(),session_id(),$newxtime, '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true));
|
||||
|
||||
setcookie(
|
||||
session_name(),
|
||||
session_id(),
|
||||
[
|
||||
'expires' => $newxtime,
|
||||
'path' => '/',
|
||||
'domain' => false,
|
||||
'secure' => ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),
|
||||
'httponly' => ((isset($arr['httponly'])) ? $arr['httponly'] : true),
|
||||
'samesite' => 'None'
|
||||
]
|
||||
);
|
||||
|
||||
$arr = array('expire' => $xtime);
|
||||
call_hooks('new_cookie', $arr);
|
||||
@@ -148,8 +172,21 @@ class Session {
|
||||
|
||||
$xtime = (($_SESSION['remember_me']) ? (60 * 60 * 24 * 365) : 0 );
|
||||
|
||||
if($xtime)
|
||||
setcookie(session_name(),session_id(),(time() + $xtime), '/', false,((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),((isset($arr['httponly'])) ? $arr['httponly'] : true));
|
||||
if($xtime) {
|
||||
setcookie(
|
||||
session_name(),
|
||||
session_id(),
|
||||
[
|
||||
'expires' => time() + $xtime,
|
||||
'path' => '/',
|
||||
'domain' => false,
|
||||
'secure' => ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),
|
||||
'httponly' => ((isset($arr['httponly'])) ? $arr['httponly'] : true),
|
||||
'samesite' => 'None'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$arr = array('expire' => $xtime);
|
||||
call_hooks('extend_cookie', $arr);
|
||||
|
||||
@@ -169,8 +206,8 @@ class Session {
|
||||
if($_SESSION['addr'] && $_SESSION['addr'] != $_SERVER['REMOTE_ADDR']) {
|
||||
logger('SECURITY: Session IP address changed: ' . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
$partial1 = substr($_SESSION['addr'], 0, strrpos($_SESSION['addr'], '.'));
|
||||
$partial2 = substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], '.'));
|
||||
$partial1 = substr($_SESSION['addr'], 0, strrpos($_SESSION['addr'], '.'));
|
||||
$partial2 = substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], '.'));
|
||||
|
||||
$paranoia = intval(get_pconfig($_SESSION['uid'], 'system', 'paranoia'));
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Zotlabs\Web;
|
||||
class SessionHandler implements \SessionHandlerInterface {
|
||||
|
||||
|
||||
function open ($s, $n) {
|
||||
function open ($s, $n) : bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
// some which call read explicitly and some that do not. So we call it explicitly
|
||||
// just after sid regeneration to force a record to exist.
|
||||
|
||||
function read ($id) {
|
||||
function read ($id) : string {
|
||||
|
||||
if($id) {
|
||||
$r = q("SELECT sess_data FROM session WHERE sid= '%s'", dbesc($id));
|
||||
@@ -36,7 +36,7 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
}
|
||||
|
||||
|
||||
function write ($id, $data) {
|
||||
function write ($id, $data) : bool {
|
||||
|
||||
// Pretend everything is hunky-dory, even though it isn't.
|
||||
// There probably isn't anything we can do about it in any event.
|
||||
@@ -49,9 +49,9 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
|
||||
// Unless we authenticate somehow, only keep a session for 5 minutes
|
||||
// The viewer can extend this by performing any web action using the
|
||||
// original cookie, but this allows us to cleanup the hundreds or
|
||||
// original cookie, but this allows us to cleanup the hundreds or
|
||||
// thousands of empty sessions left around from web crawlers which are
|
||||
// assigned cookies on each page that they never use.
|
||||
// assigned cookies on each page that they never use.
|
||||
|
||||
$expire = time() + 300;
|
||||
|
||||
@@ -74,19 +74,19 @@ class SessionHandler implements \SessionHandlerInterface {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function close() {
|
||||
|
||||
function close() : bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function destroy ($id) {
|
||||
function destroy ($id) : bool {
|
||||
q("DELETE FROM session WHERE sid = '%s'", dbesc($id));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function gc($expire) {
|
||||
function gc($expire) : int {
|
||||
q("DELETE FROM session WHERE expire < %d", dbesc(time()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
require_once('include/group.php');
|
||||
|
||||
use Zotlabs\Lib\AccessList;
|
||||
|
||||
class Collections {
|
||||
|
||||
function widget($args) {
|
||||
|
||||
if(argc() < 2)
|
||||
return;
|
||||
// return;
|
||||
|
||||
$mode = ((array_key_exists('mode',$args)) ? $args['mode'] : 'conversation');
|
||||
switch($mode) {
|
||||
@@ -49,6 +49,6 @@ class Collections {
|
||||
break;
|
||||
}
|
||||
|
||||
return group_side($every, $each, $edit, $current, $abook_id, $wmode);
|
||||
return AccessList::widget($every, $each, $edit, $current, $abook_id, $wmode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Conversations {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if (! local_channel())
|
||||
return;
|
||||
|
||||
switch(argv(1)) {
|
||||
case 'inbox':
|
||||
$mailbox = 'inbox';
|
||||
$header = t('Received Messages');
|
||||
break;
|
||||
case 'outbox':
|
||||
$mailbox = 'outbox';
|
||||
$header = t('Sent Messages');
|
||||
break;
|
||||
default:
|
||||
$mailbox = 'combined';
|
||||
$header = t('Conversations');
|
||||
break;
|
||||
}
|
||||
|
||||
$o = '';
|
||||
|
||||
// private_messages_list() can do other more complicated stuff, for now keep it simple
|
||||
$r = self::private_messages_list(local_channel(), $mailbox, \App::$pager['start'], \App::$pager['itemspage']);
|
||||
|
||||
if(! $r) {
|
||||
info( t('No messages.') . EOL);
|
||||
return $o;
|
||||
}
|
||||
|
||||
$messages = [];
|
||||
|
||||
foreach($r as $rr) {
|
||||
|
||||
$selected = ((argc() == 3) ? intval(argv(2)) == intval($rr['id']) : $r[0]['id'] == $rr['id']);
|
||||
|
||||
$messages[] = [
|
||||
'mailbox' => $mailbox,
|
||||
'id' => $rr['id'],
|
||||
'from_name' => $rr['from']['xchan_name'],
|
||||
'from_url' => chanlink_hash($rr['from_xchan']),
|
||||
'from_photo' => $rr['from']['xchan_photo_s'],
|
||||
'to_name' => $rr['to']['xchan_name'],
|
||||
'to_url' => chanlink_hash($rr['to_xchan']),
|
||||
'to_photo' => $rr['to']['xchan_photo_s'],
|
||||
'subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'),
|
||||
'delete' => t('Delete conversation'),
|
||||
'body' => $rr['body'],
|
||||
'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], 'c'),
|
||||
'seen' => $rr['seen'],
|
||||
'selected' => ((argv(1) != 'new') ? $selected : '')
|
||||
];
|
||||
}
|
||||
|
||||
$tpl = get_markup_template('mail_head.tpl');
|
||||
$o .= replace_macros($tpl, [
|
||||
'$header' => $header,
|
||||
'$messages' => $messages
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) {
|
||||
|
||||
$where = '';
|
||||
$limit = '';
|
||||
|
||||
$t0 = dba_timer();
|
||||
|
||||
if($numitems)
|
||||
$limit = " LIMIT " . intval($numitems) . " OFFSET " . intval($start);
|
||||
|
||||
if($mailbox !== '') {
|
||||
$x = q("select channel_hash from channel where channel_id = %d limit 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(! $x)
|
||||
return array();
|
||||
|
||||
$channel_hash = dbesc($x[0]['channel_hash']);
|
||||
$local_channel = intval(local_channel());
|
||||
|
||||
switch($mailbox) {
|
||||
|
||||
case 'inbox':
|
||||
$sql = "SELECT * FROM mail WHERE channel_id = $local_channel AND from_xchan != '$channel_hash' ORDER BY created DESC $limit";
|
||||
break;
|
||||
|
||||
case 'outbox':
|
||||
$sql = "SELECT * FROM mail WHERE channel_id = $local_channel AND from_xchan = '$channel_hash' ORDER BY created DESC $limit";
|
||||
break;
|
||||
|
||||
case 'combined':
|
||||
default:
|
||||
$parents = q("SELECT mail.parent_mid FROM mail LEFT JOIN conv ON mail.conv_guid = conv.guid WHERE mail.mid = mail.parent_mid AND mail.channel_id = %d ORDER BY conv.updated DESC $limit",
|
||||
intval($local_channel)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$r = null;
|
||||
|
||||
if($parents) {
|
||||
foreach($parents as $parent) {
|
||||
$all = q("SELECT * FROM mail WHERE parent_mid = '%s' AND channel_id = %d ORDER BY created DESC limit 1",
|
||||
dbesc($parent['parent_mid']),
|
||||
intval($local_channel)
|
||||
);
|
||||
|
||||
if($all) {
|
||||
foreach($all as $single) {
|
||||
$r[] = $single;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif($sql) {
|
||||
$r = q($sql);
|
||||
}
|
||||
|
||||
if(! $r) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$chans = array();
|
||||
foreach($r as $rr) {
|
||||
$s = "'" . dbesc(trim($rr['from_xchan'])) . "'";
|
||||
if(! in_array($s,$chans))
|
||||
$chans[] = $s;
|
||||
$s = "'" . dbesc(trim($rr['to_xchan'])) . "'";
|
||||
if(! in_array($s,$chans))
|
||||
$chans[] = $s;
|
||||
}
|
||||
|
||||
$c = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$chans)) . ")");
|
||||
|
||||
foreach($r as $k => $rr) {
|
||||
$r[$k]['from'] = find_xchan_in_array($rr['from_xchan'],$c);
|
||||
$r[$k]['to'] = find_xchan_in_array($rr['to_xchan'],$c);
|
||||
$r[$k]['seen'] = intval($rr['mail_seen']);
|
||||
if(intval($r[$k]['mail_obscured'])) {
|
||||
if($r[$k]['title'])
|
||||
$r[$k]['title'] = base64url_decode(str_rot47($r[$k]['title']));
|
||||
if($r[$k]['body'])
|
||||
$r[$k]['body'] = base64url_decode(str_rot47($r[$k]['body']));
|
||||
}
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Mailmenu {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if (! local_channel())
|
||||
return;
|
||||
|
||||
return replace_macros(get_markup_template('message_side.tpl'), array(
|
||||
'$title' => t('Private Mail Menu'),
|
||||
'$combined' => array(
|
||||
'label' => t('Combined View'),
|
||||
'url' => z_root() . '/mail/combined',
|
||||
'sel' => (argv(1) == 'combined' || argc() == 1),
|
||||
),
|
||||
'$inbox' => array(
|
||||
'label' => t('Inbox'),
|
||||
'url' => z_root() . '/mail/inbox',
|
||||
'sel' => (argv(1) == 'inbox'),
|
||||
),
|
||||
'$outbox' => array(
|
||||
'label' => t('Outbox'),
|
||||
'url' => z_root() . '/mail/outbox',
|
||||
'sel' => (argv(1) == 'outbox'),
|
||||
),
|
||||
/*
|
||||
'$new' => array(
|
||||
'label' => t('New Message'),
|
||||
'url' => z_root() . '/mail/new',
|
||||
'sel'=> (argv(1) == 'new'),
|
||||
)
|
||||
*/
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -219,7 +219,7 @@ class Messages {
|
||||
$entries[$i]['info'] = '';
|
||||
$entries[$i]['created'] = datetime_convert('UTC', date_default_timezone_get(), $notice['created']);
|
||||
$entries[$i]['summary'] = $summary;
|
||||
$entries[$i]['b64mid'] = basename($notice['link']);
|
||||
$entries[$i]['b64mid'] = (($notice['ntype'] & NOTIFY_INTRO) ? '' : basename($notice['link']));
|
||||
$entries[$i]['href'] = (($notice['ntype'] & NOTIFY_INTRO) ? $notice['link'] : z_root() . '/hq/' . basename($notice['link']));
|
||||
$entries[$i]['icon'] = (($notice['ntype'] & NOTIFY_INTRO) ? '<i class="fa fa-user-plus"></i>' : '');
|
||||
|
||||
|
||||
96
Zotlabs/Widget/Permcats.php
Normal file
96
Zotlabs/Widget/Permcats.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\Permcat;
|
||||
use Zotlabs\Access\PermissionLimits;
|
||||
|
||||
class Permcats {
|
||||
|
||||
function widget($arr) {
|
||||
$pcat = new Permcat(local_channel());
|
||||
$pcatlist = $pcat->listing();
|
||||
|
||||
if (!$pcatlist) {
|
||||
return;
|
||||
}
|
||||
|
||||
$roles = [];
|
||||
$active_role = '';
|
||||
|
||||
foreach($pcatlist as $pc) {
|
||||
if (!$active_role) {
|
||||
$active_role = ((argc() > 1 && $pc['name'] === hex2bin(argv(1))) ? $pc['name'] : '');
|
||||
}
|
||||
$roles[] = [
|
||||
'name' => $pc['localname'],
|
||||
'url' => z_root() . '/permcats/' . bin2hex($pc['name']),
|
||||
'active' => (argc() > 1 && $pc['name'] === hex2bin(argv(1)))
|
||||
];
|
||||
}
|
||||
|
||||
if($active_role) {
|
||||
|
||||
$roles[] = [
|
||||
'name' => '<i class="fa fa-plus"></i> ' . t('Add new role'),
|
||||
'url' => z_root() . '/permcats',
|
||||
'active' => ''
|
||||
];
|
||||
|
||||
/* 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 = [];
|
||||
|
||||
foreach ($r as $rr) {
|
||||
$members[] = [
|
||||
'name' => $rr['xchan_name'],
|
||||
'addr' => (($rr['xchan_addr']) ? $rr['xchan_addr'] : $rr['xchan_url']),
|
||||
'url' => z_root() . '/connections#' . $rr['abook_id'],
|
||||
'photo' => $rr['xchan_photo_s']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$tpl = get_markup_template("permcats_widget.tpl");
|
||||
$o .= replace_macros($tpl, [
|
||||
'$roles_label' => t('Contact roles'),
|
||||
'$members_label' => t('Role members'),
|
||||
'$roles' => $roles,
|
||||
'$members' => $members
|
||||
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
}
|
||||
55
Zotlabs/Widget/Privacygroups.php
Normal file
55
Zotlabs/Widget/Privacygroups.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use Zotlabs\Lib\AccessList;
|
||||
|
||||
class Privacygroups {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
$o = '';
|
||||
|
||||
$groups = q("SELECT id, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if (!$groups) {
|
||||
return $o;
|
||||
}
|
||||
|
||||
$menu_items = [];
|
||||
$z_root = z_root();
|
||||
$active = argv(1) ?? '';
|
||||
|
||||
foreach($groups as $group) {
|
||||
$menu_items[] = [
|
||||
'href' => $z_root . '/group/' . $group['id'],
|
||||
'label' => $group['gname'],
|
||||
'title' => '',
|
||||
'active' => ($active === $group['id']),
|
||||
'count' => count(AccessList::members(local_channel(), $group['id']))
|
||||
];
|
||||
}
|
||||
|
||||
if ($active) {
|
||||
$menu_items[] = [
|
||||
'href' => $z_root . '/group',
|
||||
'label' => '<i class="fa fa-plus"></i> ' . t('Add new group'),
|
||||
'title' => '',
|
||||
'active' => '',
|
||||
'count' => ''
|
||||
];
|
||||
}
|
||||
|
||||
$tpl = get_markup_template("widget_menu_count.tpl");
|
||||
$o .= replace_macros($tpl, [
|
||||
'$title' => t('Privacy groups'),
|
||||
'$menu_items' => $menu_items,
|
||||
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,16 @@
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use App;
|
||||
|
||||
class Profile {
|
||||
|
||||
function widget($args) {
|
||||
$block = observer_prohibited();
|
||||
return profile_sidebar(\App::$profile, $block, true, false);
|
||||
}
|
||||
if(!App::$profile['profile_uid']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$block = observer_prohibited();
|
||||
|
||||
return profile_sidebar(App::$profile, $block, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
51
Zotlabs/Widget/Tokens.php
Normal file
51
Zotlabs/Widget/Tokens.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Tokens {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
$o = '';
|
||||
|
||||
$tokens = q("SELECT atoken_id, atoken_name FROM atoken WHERE atoken_uid = %d",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if (!$tokens) {
|
||||
return $o;
|
||||
}
|
||||
|
||||
$menu_items = [];
|
||||
$z_root = z_root();
|
||||
$active = argv(1) ?? '';
|
||||
|
||||
foreach($tokens as $token) {
|
||||
$menu_items[] = [
|
||||
'href' => $z_root . '/tokens/' . $token['atoken_id'],
|
||||
'label' => $token['atoken_name'],
|
||||
'title' => '',
|
||||
'active' => ($active === $token['atoken_id'])
|
||||
];
|
||||
}
|
||||
|
||||
if ($active) {
|
||||
$menu_items[] = [
|
||||
'href' => $z_root . '/tokens',
|
||||
'label' => '<i class="fa fa-plus"></i> ' . t('Add new guest'),
|
||||
'title' => '',
|
||||
'active' => ''
|
||||
];
|
||||
}
|
||||
|
||||
$tpl = get_markup_template("widget_menu.tpl");
|
||||
$o .= replace_macros($tpl, [
|
||||
'$title' => t('Guest access'),
|
||||
'$menu_items' => $menu_items,
|
||||
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
version: 3
|
||||
version: 4
|
||||
url: $baseurl/channel/$nick, $baseurl/settings/channel_home
|
||||
requires: local_channel
|
||||
name: Channel Home
|
||||
name: Channel
|
||||
photo: icon:home
|
||||
categories: nav_featured_app, Personal
|
||||
desc: Your channel homepage featuring your personal posts.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
version: 3
|
||||
version: 5
|
||||
url: $baseurl/permcats
|
||||
requires: local_channel
|
||||
name: Permission Categories
|
||||
photo: icon:unlock-alt
|
||||
name: Contact Roles
|
||||
photo: icon:user-o
|
||||
categories: Access Control
|
||||
desc: Create and manage custom connection permission limits.
|
||||
desc: Create and manage custom contact roles.
|
||||
|
||||
@@ -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]++;
|
||||
}
|
||||
|
||||
@@ -1400,7 +1400,7 @@ function bbcode($Text, $options = []) {
|
||||
// Check for table of content without params
|
||||
while(strpos($Text,'[toc]') !== false) {
|
||||
$toc_id = 'toc-' . random_string(10);
|
||||
$Text = preg_replace("/\[toc\]/ism", '<ul id="' . $toc_id . '" class="toc" data-toc=".section-content-wrapper"></ul><script>$("#' . $toc_id . '").toc();</script>', $Text, 1);
|
||||
$Text = preg_replace("/\[toc\]/ism", '<ul id="' . $toc_id . '" class="toc"></ul><script>$(document).ready(function() { let toc_container = $("#' . $toc_id . '").parent().closest("div").attr("id") || ".section-content-wrapper"; $("#' . $toc_id . '").toc({content: "#" + toc_container, headings: "h1,h2,h3,h4"}); });</script>', $Text, 1);
|
||||
}
|
||||
// Check for table of content with params
|
||||
while(strpos($Text,'[toc') !== false) {
|
||||
|
||||
@@ -15,11 +15,13 @@ 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');
|
||||
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.
|
||||
@@ -240,7 +242,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 +327,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 +382,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 +408,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 +420,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 +453,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 +495,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'] ]);
|
||||
@@ -881,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)
|
||||
@@ -1488,6 +1494,7 @@ function profile_load($nickname, $profile = '') {
|
||||
|
||||
if($can_view_profile) {
|
||||
$online = get_online_status($nickname);
|
||||
|
||||
App::$profile['online_status'] = $online['result'];
|
||||
}
|
||||
|
||||
@@ -1965,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.
|
||||
@@ -2060,11 +2080,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",
|
||||
@@ -2280,7 +2301,7 @@ function auto_channel_create($account_id) {
|
||||
}
|
||||
}
|
||||
if(! $arr['permissions_role'])
|
||||
$arr['permissions_role'] = 'social';
|
||||
$arr['permissions_role'] = 'personal';
|
||||
|
||||
if(validate_channelname($arr['name']))
|
||||
return false;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php /** @file */
|
||||
|
||||
use Zotlabs\Daemon\Master;
|
||||
|
||||
function abook_store_lowlevel($arr) {
|
||||
|
||||
@@ -27,7 +28,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);
|
||||
@@ -112,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;
|
||||
}
|
||||
|
||||
@@ -284,17 +286,18 @@ function remove_all_xchan_resources($xchan, $channel_id = 0) {
|
||||
|
||||
$dirmode = intval(get_config('system','directory_mode'));
|
||||
|
||||
|
||||
$r = q("delete from photo where xchan = '%s'",
|
||||
dbesc($xchan)
|
||||
);
|
||||
|
||||
$r = q("select resource_id, resource_type, uid, id from item where ( author_xchan = '%s' or owner_xchan = '%s' ) ",
|
||||
dbesc($xchan),
|
||||
dbesc($xchan)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
drop_item($rr,false);
|
||||
drop_item($rr['id'],false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,52 +378,22 @@ function contact_remove($channel_id, $abook_id) {
|
||||
if(intval($abook['abook_self']))
|
||||
return false;
|
||||
|
||||
$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']),
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
$already_saved = [];
|
||||
foreach($r as $rr) {
|
||||
$w = $x = $y = null;
|
||||
// if this is an atoken, delete the atoken record
|
||||
|
||||
// optimise so we only process newly seen parent items
|
||||
if (in_array($rr['parent'],$already_saved)) {
|
||||
continue;
|
||||
}
|
||||
// if this isn't the parent, fetch the parent's item_retained and item_starred to see if the conversation
|
||||
// should be retained
|
||||
if($rr['id'] != $rr['parent']) {
|
||||
$w = q("select id, item_retained, item_starred from item where id = %d",
|
||||
intval($rr['parent'])
|
||||
);
|
||||
if($w) {
|
||||
// see if the conversation was filed
|
||||
$x = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1",
|
||||
intval(TERM_OBJ_POST),
|
||||
intval($w[0]['id']),
|
||||
intval(TERM_FILE)
|
||||
);
|
||||
if (intval($w[0]['item_retained']) || intval($w[0]['item_starred']) || $x) {
|
||||
$already_saved[] = $rr['parent'];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// see if this item was filed
|
||||
$y = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1",
|
||||
intval(TERM_OBJ_POST),
|
||||
intval($rr['id']),
|
||||
intval(TERM_FILE)
|
||||
);
|
||||
if ($y) {
|
||||
continue;
|
||||
}
|
||||
drop_item($rr['id'],false);
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
// remove items in the background as this can take some time
|
||||
Master::Summon(['Delxitems', $channel_id, $abook['abook_xchan']]);
|
||||
|
||||
q("delete from abook where abook_id = %d and abook_channel = %d",
|
||||
intval($abook['abook_id']),
|
||||
intval($channel_id)
|
||||
@@ -449,7 +422,62 @@ function contact_remove($channel_id, $abook_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function remove_abook_items($channel_id, $xchan_hash) {
|
||||
|
||||
$r = q("select id from item where (owner_xchan = '%s' or author_xchan = '%s') and uid = %d and item_retained = 0 and item_starred = 0",
|
||||
dbesc($xchan_hash),
|
||||
dbesc($xchan_hash),
|
||||
intval($channel_id)
|
||||
);
|
||||
if (! $r) {
|
||||
return;
|
||||
}
|
||||
|
||||
$already_saved = [];
|
||||
foreach ($r as $rr) {
|
||||
$w = $x = $y = null;
|
||||
|
||||
// optimise so we only process newly seen parent items
|
||||
if (in_array($rr['parent'], $already_saved)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if this isn't the parent, fetch the parent's item_retained and item_starred to see if the conversation
|
||||
// should be retained
|
||||
if ($rr['id'] != $rr['parent']) {
|
||||
$w = q("select id, item_retained, item_starred from item where id = %d",
|
||||
intval($rr['parent'])
|
||||
);
|
||||
|
||||
if ($w) {
|
||||
// see if the conversation was filed
|
||||
$x = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1",
|
||||
intval(TERM_OBJ_POST),
|
||||
intval($w[0]['id']),
|
||||
intval(TERM_FILE)
|
||||
);
|
||||
|
||||
if (intval($w[0]['item_retained']) || intval($w[0]['item_starred']) || $x) {
|
||||
$already_saved[] = $rr['parent'];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// see if this item was filed
|
||||
$y = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1",
|
||||
intval(TERM_OBJ_POST),
|
||||
intval($rr['id']),
|
||||
intval(TERM_FILE)
|
||||
);
|
||||
|
||||
if ($y) {
|
||||
continue;
|
||||
}
|
||||
|
||||
drop_item($rr['id'],false);
|
||||
}
|
||||
}
|
||||
|
||||
function random_profile() {
|
||||
$randfunc = db_getfunc('rand');
|
||||
|
||||
@@ -100,6 +100,10 @@ function categories_widget($baseurl,$selected = '') {
|
||||
\Zotlabs\Daemon\Master::Summon([ 'Cache_query', $key, base64_encode(json_encode($arr)) ]);
|
||||
}
|
||||
|
||||
if (!$content) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
$r = unserialize($content);
|
||||
|
||||
$terms = [];
|
||||
|
||||
@@ -558,7 +558,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
||||
$page_writeable = ($profile_owner == local_channel());
|
||||
|
||||
if (!$update) {
|
||||
$tab = notags(trim($_GET['tab']));
|
||||
$tab = notags(trim((string)$_GET['tab']));
|
||||
if ($tab === 'posts') {
|
||||
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
|
||||
// because browser prefetching might change it on us. We have to deliver it with the page.
|
||||
@@ -775,6 +775,12 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
||||
|
||||
$conv_link = ((in_array($item['item_type'],[ ITEM_TYPE_CARD, ITEM_TYPE_ARTICLE] )) ? $item['plink'] : z_root() . '/' . $conv_link_module . '/' . gen_link_id($conv_link_mid));
|
||||
|
||||
$contact = [];
|
||||
|
||||
if(App::$contacts && array_key_exists($item['author_xchan'],App::$contacts)) {
|
||||
$contact = App::$contacts[$item['author_xchan']];
|
||||
}
|
||||
|
||||
$tmp_item = array(
|
||||
'template' => $tpl,
|
||||
'toplevel' => 'toplevel_item',
|
||||
@@ -838,7 +844,8 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
||||
'wait' => t('Please wait'),
|
||||
'thread_level' => 1,
|
||||
'has_tags' => $has_tags,
|
||||
'is_new' => $is_new
|
||||
'is_new' => $is_new,
|
||||
'contact_id' => (($contact) ? $contact['abook_id'] : '')
|
||||
);
|
||||
|
||||
$arr = array('item' => $item, 'output' => $tmp_item);
|
||||
@@ -967,7 +974,7 @@ function best_link_url($item) {
|
||||
}
|
||||
}
|
||||
if(! $best_url) {
|
||||
if(strlen($item['author-link']))
|
||||
if($item['author-link'])
|
||||
$best_url = $item['author-link'];
|
||||
else
|
||||
$best_url = $item['url'];
|
||||
@@ -1061,7 +1068,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';
|
||||
}
|
||||
}
|
||||
@@ -1070,7 +1077,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 +1093,9 @@ function thread_author_menu($item, $mode = '') {
|
||||
'title' => t('View Profile'),
|
||||
'icon' => 'fw',
|
||||
'action' => '',
|
||||
'href' => $profile_link
|
||||
'href' => $profile_link,
|
||||
'data' => '',
|
||||
'class' => ''
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1096,7 +1105,9 @@ function thread_author_menu($item, $mode = '') {
|
||||
'title' => t('Recent Activity'),
|
||||
'icon' => 'fw',
|
||||
'action' => '',
|
||||
'href' => $posts_link
|
||||
'href' => $posts_link,
|
||||
'data' => '',
|
||||
'class' => ''
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1107,6 +1118,8 @@ function thread_author_menu($item, $mode = '') {
|
||||
'icon' => 'fw',
|
||||
'action' => 'doFollowAuthor(\'' . $follow_url . '\'); return false;',
|
||||
'href' => '#',
|
||||
'data' => '',
|
||||
'class' => ''
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1116,7 +1129,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 +1141,9 @@ function thread_author_menu($item, $mode = '') {
|
||||
'title' => t('Message'),
|
||||
'icon' => 'fw',
|
||||
'action' => '',
|
||||
'href' => $pm_url
|
||||
'href' => $pm_url,
|
||||
'data' => '',
|
||||
'class' => ''
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1136,7 +1153,9 @@ function thread_author_menu($item, $mode = '') {
|
||||
'title' => t('Ratings'),
|
||||
'icon' => 'fw',
|
||||
'action' => '',
|
||||
'href' => $ratings_url
|
||||
'href' => $ratings_url,
|
||||
'data' => '',
|
||||
'class' => ''
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1146,7 +1165,9 @@ function thread_author_menu($item, $mode = '') {
|
||||
'title' => t('Poke'),
|
||||
'icon' => 'fw',
|
||||
'action' => '',
|
||||
'href' => $poke_link
|
||||
'href' => $poke_link,
|
||||
'data' => '',
|
||||
'class' => ''
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class DBA {
|
||||
* @param bool $install Defaults to false
|
||||
* @return null|dba_driver A database driver object (dba_pdo) or null if no driver found.
|
||||
*/
|
||||
static public function dba_factory($server,$port,$user,$pass,$db,$dbtype,$install = false) {
|
||||
static public function dba_factory($server,$port,$user,$pass,$db,$dbtype,$db_charset,$install = false) {
|
||||
|
||||
self::$dba = null;
|
||||
self::$dbtype = intval($dbtype);
|
||||
@@ -65,7 +65,7 @@ class DBA {
|
||||
}
|
||||
|
||||
require_once('include/dba/dba_pdo.php');
|
||||
self::$dba = new dba_pdo($server,self::$scheme,$port,$user,$pass,$db,$install);
|
||||
self::$dba = new dba_pdo($server,self::$scheme,$port,$user,$pass,$db,$db_charset,$install);
|
||||
|
||||
define('NULL_DATE', self::$null_date);
|
||||
define('ACTIVE_DBTYPE', self::$dbtype);
|
||||
@@ -105,7 +105,7 @@ abstract class dba_driver {
|
||||
* @param string $db database name
|
||||
* @return bool
|
||||
*/
|
||||
abstract function connect($server, $scheme, $port, $user, $pass, $db);
|
||||
abstract function connect($server, $scheme, $port, $user, $pass, $db, $db_charset);
|
||||
|
||||
/**
|
||||
* @brief Perform a DB query with the SQL statement $sql.
|
||||
@@ -139,11 +139,11 @@ abstract class dba_driver {
|
||||
*/
|
||||
abstract function getdriver();
|
||||
|
||||
function __construct($server, $scheme, $port, $user,$pass,$db,$install = false) {
|
||||
if(($install) && (! $this->install($server, $scheme, $port, $user, $pass, $db))) {
|
||||
function __construct($server, $scheme, $port, $user,$pass,$db,$db_charset,$install = false) {
|
||||
if(($install) && (! $this->install($server, $scheme, $port, $user, $pass, $db, $db_charset))) {
|
||||
return;
|
||||
}
|
||||
$this->connect($server, $scheme, $port, $user, $pass, $db);
|
||||
$this->connect($server, $scheme, $port, $user, $pass, $db, $db_charset);
|
||||
}
|
||||
|
||||
function get_null_date() {
|
||||
|
||||
@@ -14,7 +14,7 @@ class dba_pdo extends dba_driver {
|
||||
* {@inheritDoc}
|
||||
* @see dba_driver::connect()
|
||||
*/
|
||||
function connect($server, $scheme, $port, $user, $pass, $db) {
|
||||
function connect($server, $scheme, $port, $user, $pass, $db, $db_charset) {
|
||||
|
||||
$this->driver_dbtype = $scheme;
|
||||
|
||||
@@ -27,6 +27,13 @@ class dba_pdo extends dba_driver {
|
||||
|
||||
$dsn .= ';dbname=' . $db;
|
||||
|
||||
if ($this->driver_dbtype === 'mysql') {
|
||||
$dsn .= ';charset=' . $db_charset;
|
||||
}
|
||||
else {
|
||||
$dsn .= ";options='--client_encoding=" . $db_charset . "'";
|
||||
}
|
||||
|
||||
try {
|
||||
$this->db = new PDO($dsn,$user,$pass);
|
||||
$this->db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
@@ -1180,7 +1180,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
else {
|
||||
$name = $author['author_name'];
|
||||
}
|
||||
$x = import_author_unknown(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
|
||||
$x = import_author_rss(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
|
||||
if($x)
|
||||
$datarray['author_xchan'] = $x;
|
||||
}
|
||||
@@ -1440,7 +1440,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
else {
|
||||
$name = $author['author_name'];
|
||||
}
|
||||
$x = import_author_unknown(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
|
||||
$x = import_author_rss(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
|
||||
if($x)
|
||||
$datarray['author_xchan'] = $x;
|
||||
}
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -16,6 +16,8 @@ use Zotlabs\Daemon\Master;
|
||||
*/
|
||||
function hubloc_store_lowlevel($arr) {
|
||||
|
||||
$update = ((array_key_exists('hubloc_id',$arr) && $arr['hubloc_id']) ? 'hubloc_id = ' . intval($arr['hubloc_id']) : false);
|
||||
|
||||
$store = [
|
||||
'hubloc_guid' => ((array_key_exists('hubloc_guid',$arr)) ? $arr['hubloc_guid'] : ''),
|
||||
'hubloc_guid_sig' => ((array_key_exists('hubloc_guid_sig',$arr)) ? $arr['hubloc_guid_sig'] : ''),
|
||||
@@ -40,7 +42,7 @@ function hubloc_store_lowlevel($arr) {
|
||||
'hubloc_deleted' => ((array_key_exists('hubloc_deleted',$arr)) ? $arr['hubloc_deleted'] : 0)
|
||||
];
|
||||
|
||||
return create_table_from_array('hubloc', $store);
|
||||
return (($update) ? update_table_from_array('hubloc', $store, $update) : create_table_from_array('hubloc', $store));
|
||||
}
|
||||
|
||||
function site_store_lowlevel($arr) {
|
||||
@@ -283,6 +285,13 @@ function hubloc_change_primary($hubloc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function hubloc_delete($hubloc) {
|
||||
if (is_array($hubloc) && array_key_exists('hubloc_id', $hubloc)) {
|
||||
q("UPDATE hubloc SET hubloc_deleted = 1 WHERE hubloc_id = %d",
|
||||
intval($hubloc['hubloc_id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mark a hubloc as down.
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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')) {
|
||||
@@ -476,7 +476,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
|
||||
$arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments'));
|
||||
|
||||
if ((! $arr['plink']) && (intval($arr['item_thread_top']))) {
|
||||
$arr['plink'] = substr(z_root() . '/channel/' . $channel['channel_address'] . '/' . (filter_var($arr['mid'], FILTER_VALIDATE_URL) === false ? '?f=&mid=' : '') . urlencode($arr['mid']),0,190);
|
||||
$arr['plink'] = $arr['mid'];
|
||||
}
|
||||
|
||||
|
||||
@@ -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';
|
||||
@@ -1443,7 +1446,7 @@ function activity_sanitise($arr) {
|
||||
if(is_array($x))
|
||||
$ret[$k] = activity_sanitise($x);
|
||||
else
|
||||
$ret[$k] = htmlspecialchars($x, ENT_COMPAT, 'UTF-8', false);
|
||||
$ret[$k] = htmlspecialchars((string)$x, ENT_COMPAT, 'UTF-8', false);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
@@ -1622,9 +1625,9 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : '');
|
||||
$arr['summary'] = ((array_key_exists('summary',$arr) && strlen($arr['summary'])) ? trim($arr['summary']) : '');
|
||||
$arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : '');
|
||||
$arr['title'] = ((array_key_exists('title',$arr) && $arr['title']) ? trim($arr['title']) : '');
|
||||
$arr['summary'] = ((array_key_exists('summary',$arr) && $arr['summary']) ? trim($arr['summary']) : '');
|
||||
$arr['body'] = ((array_key_exists('body',$arr) && $arr['body']) ? trim($arr['body']) : '');
|
||||
|
||||
$arr['allow_cid'] = ((x($arr,'allow_cid')) ? trim($arr['allow_cid']) : '');
|
||||
$arr['allow_gid'] = ((x($arr,'allow_gid')) ? trim($arr['allow_gid']) : '');
|
||||
@@ -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_hidden'] = 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) {
|
||||
@@ -4306,7 +4438,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
|
||||
);
|
||||
}
|
||||
|
||||
if(strlen($arr['file'])) {
|
||||
if($arr['file']) {
|
||||
$sql_extra .= term_query('item',$arr['files'],TERM_FILE);
|
||||
}
|
||||
|
||||
@@ -4640,8 +4772,9 @@ function send_profile_photo_activity($channel,$photo,$profile) {
|
||||
|
||||
$arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext;
|
||||
|
||||
$acl = new AccessList($channel);
|
||||
$acl = new Zotlabs\Access\AccessList($channel);
|
||||
$x = $acl->get();
|
||||
|
||||
$arr['allow_cid'] = $x['allow_cid'];
|
||||
|
||||
$arr['allow_gid'] = $x['allow_gid'];
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -400,6 +400,18 @@ function z_post_url($url, $params, $redirects = 0, $opts = array()) {
|
||||
return($ret);
|
||||
}
|
||||
|
||||
function z_curl_error($ret) {
|
||||
$output = EMPTY_STR;
|
||||
if (isset($ret['debug'])) {
|
||||
$output .= datetime_convert() . EOL;
|
||||
$output .= t('url: ') . $ret['debug']['url'] . EOL;
|
||||
$output .= t('error_code: ') . $ret['debug']['error_code'] . EOL;
|
||||
$output .= t('error_string: ') . $ret['error'] . EOL;
|
||||
$output .= t('content-type: ') . $ret['debug']['content_type'] . EOL;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function json_return_and_die($x, $content_type = 'application/json') {
|
||||
header("Content-type: $content_type");
|
||||
echo json_encode($x);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -104,7 +87,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 +98,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 +106,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 +116,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 +133,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 +141,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 +158,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 +169,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 +190,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 +204,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 +214,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_
|
||||
|
||||
// No permissions allowed.
|
||||
|
||||
$ret[$perm_name] = false;
|
||||
$ret[$perm_name] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
|
||||
@@ -742,7 +742,9 @@ function get_theme_info($theme){
|
||||
'credits' => '',
|
||||
'maintainer' => array(),
|
||||
'experimental' => false,
|
||||
'unsupported' => false
|
||||
'unsupported' => false,
|
||||
'theme_color' => '',
|
||||
'background_color' => ''
|
||||
);
|
||||
|
||||
if(file_exists("view/theme/$theme/experimental"))
|
||||
|
||||
@@ -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_network' => 'token',
|
||||
'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,15 +155,25 @@ 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)
|
||||
);
|
||||
|
||||
q("update xchan set xchan_deleted = 1 where xchan_hash = '%s'",
|
||||
dbesc($atoken_xchan)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +220,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))
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php /** @file */
|
||||
|
||||
|
||||
function contact_profile_assign($current) {
|
||||
function contact_profile_assign($current, $label = '') {
|
||||
|
||||
$r = q("SELECT profile_guid, profile_name FROM profile WHERE uid = %d",
|
||||
intval($_SESSION['uid'])
|
||||
@@ -13,9 +13,13 @@ function contact_profile_assign($current) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!$label) {
|
||||
$label = t('Select a profile to assign to this contact');
|
||||
}
|
||||
|
||||
$select = [
|
||||
'profile_assign',
|
||||
t('Profile to assign new connections'),
|
||||
$label,
|
||||
$current,
|
||||
'',
|
||||
$options
|
||||
@@ -70,7 +74,7 @@ function gender_selector($current="",$suffix="") {
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
function gender_selector_min($current="",$suffix="") {
|
||||
$o = '';
|
||||
@@ -87,7 +91,7 @@ function gender_selector_min($current="",$suffix="") {
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -107,7 +111,7 @@ function sexpref_selector($current="",$suffix="") {
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function sexpref_selector_min($current="",$suffix="") {
|
||||
@@ -125,7 +129,7 @@ function sexpref_selector_min($current="",$suffix="") {
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -144,7 +148,7 @@ function marital_selector($current="",$suffix="") {
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
function marital_selector_min($current="",$suffix="") {
|
||||
$o = '';
|
||||
@@ -161,5 +165,5 @@ function marital_selector_min($current="",$suffix="") {
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
251
include/text.php
251
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");
|
||||
|
||||
@@ -416,6 +417,9 @@ function xmlify($str) {
|
||||
|
||||
//$buffer = '';
|
||||
|
||||
if (!$str)
|
||||
return EMPTY_STR;
|
||||
|
||||
if(is_array($str)) {
|
||||
|
||||
// allow to fall through so we ge a PHP error, as the log statement will
|
||||
@@ -481,6 +485,9 @@ function unxmlify($s) {
|
||||
return $ret;
|
||||
*/
|
||||
|
||||
if (!$s)
|
||||
return EMPTY_STR;
|
||||
|
||||
if(is_array($s)) {
|
||||
|
||||
// allow to fall through so we ge a PHP error, as the log statement will
|
||||
@@ -585,6 +592,7 @@ function alt_pager($i, $more = '', $less = '') {
|
||||
'$less' => $less,
|
||||
'$more' => $more,
|
||||
'$url' => $url,
|
||||
'$url_appendix' => ((strpos($url, '?')) ? '&' : '?'),
|
||||
'$prevpage' => App::$pager['page'] - 1,
|
||||
'$nextpage' => App::$pager['page'] + 1,
|
||||
));
|
||||
@@ -838,7 +846,7 @@ function activity_match($haystack,$needle) {
|
||||
|
||||
if($needle) {
|
||||
foreach($needle as $n) {
|
||||
if(($haystack === $n) || (strtolower(basename($n)) === strtolower(basename($haystack)))) {
|
||||
if(($haystack === $n) || (strtolower(basename((string)$n)) === strtolower(basename((string)$haystack)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -864,6 +872,7 @@ function get_tags($s) {
|
||||
// ignore anything in a code or svg block
|
||||
$s = preg_replace('/\[code(.*?)\](.*?)\[\/code\]/sm','',$s);
|
||||
$s = preg_replace('/\[svg(.*?)\](.*?)\[\/svg\]/sm','',$s);
|
||||
$s = preg_replace('/\[toc(.*?)\]/sm','',$s);
|
||||
|
||||
// ignore anything in [style= ]
|
||||
$s = preg_replace('/\[style=(.*?)\]/sm','',$s);
|
||||
@@ -994,7 +1003,7 @@ function contact_block() {
|
||||
$is_owner = ((local_channel() && local_channel() == App::$profile['uid']) ? true : false);
|
||||
$sql_extra = '';
|
||||
|
||||
$abook_flags = " and abook_pending = 0 and abook_self = 0 ";
|
||||
$abook_flags = " and abook_pending = 0 and abook_self = 0 and abook_blocked = 0 and abook_ignored = 0 ";
|
||||
|
||||
if(! $is_owner) {
|
||||
$abook_flags .= " and abook_hidden = 0 ";
|
||||
@@ -1008,56 +1017,58 @@ function contact_block() {
|
||||
$abook_flags and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra",
|
||||
intval(App::$profile['uid'])
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
$total = intval($r[0]['total']);
|
||||
}
|
||||
|
||||
if(! $total) {
|
||||
$contacts = t('No connections');
|
||||
$micropro = null;
|
||||
} else {
|
||||
return $o;
|
||||
}
|
||||
|
||||
$randfunc = db_getfunc('RAND');
|
||||
$randfunc = db_getfunc('RAND');
|
||||
|
||||
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d $abook_flags and abook_archived = 0 and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra ORDER BY $randfunc LIMIT %d",
|
||||
intval(App::$profile['uid']),
|
||||
intval($shown)
|
||||
);
|
||||
$r = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook.abook_xchan = xchan.xchan_hash WHERE abook_channel = %d $abook_flags and abook_archived = 0 and xchan_orphan = 0 and xchan_deleted = 0 $sql_extra ORDER BY $randfunc LIMIT %d",
|
||||
intval(App::$profile['uid']),
|
||||
intval($shown)
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
$contacts = t('Connections');
|
||||
$micropro = [];
|
||||
foreach($r as $rr) {
|
||||
if(! $r) {
|
||||
return $o;
|
||||
}
|
||||
|
||||
// There is no setting to discover if you are bi-directionally connected
|
||||
// Use the ability to post comments as an indication that this relationship is more
|
||||
// than wishful thinking; even though soapbox channels and feeds will disable it.
|
||||
$rr['perminfo']['connpermcount']=0;
|
||||
$rr['perminfo']['connperms']=t('Accepts').': ';
|
||||
if(intval(get_abconfig(App::$profile['uid'],$rr['xchan_hash'],'their_perms','post_comments'))) {
|
||||
$rr['perminfo']['connpermcount']++;
|
||||
$rr['perminfo']['connperms'] .= t('Comments');
|
||||
}
|
||||
if(intval(get_abconfig(App::$profile['uid'],$rr['xchan_hash'],'their_perms','send_stream'))) {
|
||||
$rr['perminfo']['connpermcount']++;
|
||||
$rr['perminfo']['connperms'] = ($rr['perminfo']['connperms']) ? $rr['perminfo']['connperms'] . ', ' : $rr['perminfo']['connperms'] ;
|
||||
$rr['perminfo']['connperms'] .= t('Stream items');
|
||||
}
|
||||
if(intval(get_abconfig(App::$profile['uid'],$rr['xchan_hash'],'their_perms','post_wall'))) {
|
||||
$rr['perminfo']['connpermcount']++;
|
||||
$rr['perminfo']['connperms'] = ($rr['perminfo']['connperms']) ? $rr['perminfo']['connperms'] . ', ' : $rr['perminfo']['connperms'] ;
|
||||
$rr['perminfo']['connperms'] .= t('Wall posts');
|
||||
}
|
||||
$contacts = t('Connections');
|
||||
$micropro = [];
|
||||
foreach($r as $rr) {
|
||||
|
||||
if ($rr['perminfo']['connpermcount'] == 0) {
|
||||
$rr['perminfo']['connperms'] .= t('Nothing');
|
||||
}
|
||||
|
||||
if(!$is_owner && $rr['perminfo']['connpermcount'] !== 0)
|
||||
unset($rr['perminfo']);
|
||||
|
||||
$micropro[] = micropro($rr,true,'mpfriend');
|
||||
}
|
||||
// There is no setting to discover if you are bi-directionally connected
|
||||
// Use the ability to post comments as an indication that this relationship is more
|
||||
// than wishful thinking; even though soapbox channels and feeds will disable it.
|
||||
$rr['perminfo']['connpermcount']=0;
|
||||
$rr['perminfo']['connperms']=t('Accepts').': ';
|
||||
if(intval(get_abconfig(App::$profile['uid'],$rr['xchan_hash'],'their_perms','post_comments'))) {
|
||||
$rr['perminfo']['connpermcount']++;
|
||||
$rr['perminfo']['connperms'] .= t('Comments');
|
||||
}
|
||||
if(intval(get_abconfig(App::$profile['uid'],$rr['xchan_hash'],'their_perms','send_stream'))) {
|
||||
$rr['perminfo']['connpermcount']++;
|
||||
$rr['perminfo']['connperms'] = ($rr['perminfo']['connperms']) ? $rr['perminfo']['connperms'] . ', ' : $rr['perminfo']['connperms'] ;
|
||||
$rr['perminfo']['connperms'] .= t('Stream items');
|
||||
}
|
||||
if(intval(get_abconfig(App::$profile['uid'],$rr['xchan_hash'],'their_perms','post_wall'))) {
|
||||
$rr['perminfo']['connpermcount']++;
|
||||
$rr['perminfo']['connperms'] = ($rr['perminfo']['connperms']) ? $rr['perminfo']['connperms'] . ', ' : $rr['perminfo']['connperms'] ;
|
||||
$rr['perminfo']['connperms'] .= t('Wall posts');
|
||||
}
|
||||
|
||||
if ($rr['perminfo']['connpermcount'] == 0) {
|
||||
$rr['perminfo']['connperms'] .= t('Nothing');
|
||||
}
|
||||
|
||||
if(!$is_owner && $rr['perminfo']['connpermcount'] !== 0)
|
||||
unset($rr['perminfo']);
|
||||
|
||||
$micropro[] = micropro($rr,true,'mpfriend');
|
||||
}
|
||||
|
||||
$tpl = get_markup_template('contact_block.tpl');
|
||||
@@ -1487,6 +1498,10 @@ function day_translate($s) {
|
||||
* @return string
|
||||
*/
|
||||
function normalise_link($url) {
|
||||
if (!$url) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
$ret = str_replace(array('https:', '//www.'), array('http:', '//'), $url);
|
||||
|
||||
return(rtrim($ret, '/'));
|
||||
@@ -1714,7 +1729,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) {
|
||||
@@ -1753,6 +1768,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,17 +1870,29 @@ 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);
|
||||
|
||||
//logger('format_poll: ' . print_r($item,true));
|
||||
$activated = ((local_channel() && local_channel() == $item['uid']) ? true : false);
|
||||
$output = $s . EOL. EOL;
|
||||
$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);
|
||||
}
|
||||
|
||||
$output .= EOL . EOL;
|
||||
|
||||
if ($act['type'] === 'Question') {
|
||||
if ($activated and $commentable) {
|
||||
$output .= '<form id="question-form-' . $item['id'] . '" >';
|
||||
}
|
||||
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);
|
||||
@@ -1875,15 +1903,34 @@ function format_poll($item,$s,$opts) {
|
||||
$total = 0;
|
||||
}
|
||||
if ($activated && $commentable) {
|
||||
$output .= '<input type="checkbox" name="answer[]" value="' . htmlspecialchars($text) . '"> ' . $text . '</input>' . ' (' . $total . ')' . EOL;
|
||||
//$output .= '<input type="checkbox" name="answer[]" value="' . htmlspecialchars($text) . '"> ' . $text . '</input>' . ' (' . $total . ')' . EOL;
|
||||
|
||||
$output .= '<input type="checkbox" name="answer[]" value="' . htmlspecialchars($text) . '"> <strong>' . $text . '</strong>' . EOL;
|
||||
$output .= '<div class="progress bg-secondary bg-opacity-25" style="height: 3px;">';
|
||||
$output .= '<div class="progress-bar bg-info" role="progressbar" style="width: ' . (($totalResponses) ? intval($total / $totalResponses * 100) : 0). '%;" aria-valuenow="" aria-valuemin="0" aria-valuemax="100"></div>';
|
||||
$output .= '</div>';
|
||||
$output .= '<div class="text-muted"><small>' . sprintf(tt('%d Vote', '%d Votes', $total, 'noun'), $total) . ' | ' . (($totalResponses) ? intval($total / $totalResponses * 100) . '%' : '0%') . '</small></div>';
|
||||
$output .= EOL;
|
||||
}
|
||||
else {
|
||||
$output .= '[ ] ' . $text . ' (' . $total . ')' . EOL;
|
||||
//$output .= '[ ] ' . $text . ' (' . $total . ')' . EOL;
|
||||
$output .= '<input type="checkbox" name="answer[]" value="' . htmlspecialchars($text) . '" disabled="disabled"> <strong>' . $text . '</strong>' . EOL;
|
||||
$output .= '<div class="progress bg-secondary bg-opacity-25" style="height: 3px;">';
|
||||
$output .= '<div class="progress-bar bg-info" role="progressbar" style="width: ' . (($totalResponses) ? intval($total / $totalResponses * 100) : 0) . '%;" aria-valuenow="" aria-valuemin="0" aria-valuemax="100"></div>';
|
||||
$output .= '</div>';
|
||||
$output .= '<div class="text-muted"><small>' . sprintf(tt('%d Vote', '%d Votes', $total, 'noun'), $total) . ' | ' . (($totalResponses) ? intval($total / $totalResponses * 100) . '%' : '0%') . '</small></div>';
|
||||
$output .= EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 +1941,48 @@ function format_poll($item,$s,$opts) {
|
||||
$total = 0;
|
||||
}
|
||||
if ($activated && $commentable) {
|
||||
$output .= '<input type="radio" name="answer" value="' . htmlspecialchars($text) . '"> ' . $text . '</input>' . ' (' . $total . ')' . EOL;
|
||||
$output .= '<input type="radio" name="answer" value="' . htmlspecialchars($text) . '"> <strong>' . $text . '</strong>' . EOL;
|
||||
$output .= '<div class="progress bg-secondary bg-opacity-25" style="height: 3px;">';
|
||||
$output .= '<div class="progress-bar bg-info" role="progressbar" style="width: ' . (($totalResponses) ? intval($total / $totalResponses * 100) : 0). '%;" aria-valuenow="" aria-valuemin="0" aria-valuemax="100"></div>';
|
||||
$output .= '</div>';
|
||||
$output .= '<div class="text-muted"><small>' . sprintf(tt('%d Vote', '%d Votes', $total, 'noun'), $total) . ' | ' . (($totalResponses) ? intval($total / $totalResponses * 100) . '%' : '0%') . '</small></div>';
|
||||
$output .= EOL;
|
||||
}
|
||||
|
||||
else {
|
||||
$output .= '( ) ' . $text . ' (' . $total . ')' . EOL;
|
||||
$output .= '<input type="radio" name="answer" value="' . htmlspecialchars($text) . '" disabled="disabled"> <strong>' . $text . '</strong>' . EOL;
|
||||
$output .= '<div class="progress bg-secondary bg-opacity-25" style="height: 3px;">';
|
||||
$output .= '<div class="progress-bar bg-info" role="progressbar" style="width: ' . (($totalResponses) ? intval($total / $totalResponses * 100) : 0) . '%;" aria-valuenow="" aria-valuemin="0" aria-valuemax="100"></div>';
|
||||
$output .= '</div>';
|
||||
$output .= '<div class="text-muted"><small>' . sprintf(tt('%d Vote', '%d Votes', $total, 'noun'), $total) . ' | ' . (($totalResponses) ? intval($total / $totalResponses * 100) . '%' : '0%') . '</small></div>';
|
||||
$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'), '<span class="autotime" title="' . $t . '"></span>');
|
||||
}
|
||||
$output .= EOL . '<div>' . $message . '</div>';
|
||||
}
|
||||
if ($activated and $commentable) {
|
||||
$output .= EOL . '<input type="button" class="btn btn-std btn-success" name="vote" value="' . t("Vote") . '" onclick="submitPoll(' . $item['id'] . '); return false;">'. '</form>';
|
||||
}
|
||||
|
||||
$output .= '<div class="mb-3">' . $message . '</div>';
|
||||
|
||||
if ($activated && $commentable && !$closed) {
|
||||
$output .= '<input type="button" class="btn btn-std btn-success" name="vote" value="' . t("Vote") . '" onclick="submitPoll(' . $item['id'] . '); return false;">'. '</form>';
|
||||
}
|
||||
|
||||
if (strpos($item['body'], '[/share]') !== false) {
|
||||
$output .= '</div></div>';
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
@@ -2534,7 +2600,7 @@ function xchan_query(&$items, $abook = true, $effective_uid = 0) {
|
||||
$chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash
|
||||
where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") and hubloc_primary = 1");
|
||||
}
|
||||
$xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$arr)) . ") and xchan_network in ('rss','unknown', 'anon')");
|
||||
$xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$arr)) . ") and xchan_network in ('rss','unknown', 'anon', 'token')");
|
||||
if(! $chans)
|
||||
$chans = $xchans;
|
||||
else
|
||||
@@ -2989,7 +3055,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::by_name($profile_uid,$name);
|
||||
|
||||
if($grp) {
|
||||
$g = q("select hash from pgrp where id = %d and visible = 1 limit 1",
|
||||
@@ -3532,6 +3598,45 @@ function create_table_from_array($table, $arr, $binary_fields = []) {
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
function update_table_from_array($table, $arr, $where, $binary_fields = []) {
|
||||
|
||||
if (! ($arr && $table)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$columns = db_columns($table);
|
||||
|
||||
$clean = [];
|
||||
foreach ($arr as $k => $v) {
|
||||
if (! in_array($k, $columns)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$matches = false;
|
||||
if (preg_match('/([^a-zA-Z0-9\-\_\.])/', $k, $matches)) {
|
||||
return false;
|
||||
}
|
||||
if (in_array($k, $binary_fields)) {
|
||||
$clean[$k] = dbescbin($v);
|
||||
} else {
|
||||
$clean[$k] = dbesc($v);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "UPDATE " . TQUOT . $table . TQUOT . " SET ";
|
||||
|
||||
foreach ($clean as $k => $v) {
|
||||
$sql .= TQUOT . $k . TQUOT . ' = "' . $v . '",';
|
||||
}
|
||||
|
||||
$sql = rtrim($sql,',');
|
||||
|
||||
$r = dbq($sql . " WHERE " . $where);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
function share_shield($m) {
|
||||
return str_replace($m[1],'!=+=+=!' . base64url_encode($m[1]) . '=+!=+!=',$m[0]);
|
||||
}
|
||||
@@ -3692,6 +3797,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 +3875,7 @@ function get_forum_channels($uid) {
|
||||
}
|
||||
|
||||
App::$data['forum_channels'] = $r;
|
||||
*/
|
||||
|
||||
return $r;
|
||||
|
||||
@@ -3828,6 +3941,26 @@ function array_path_exists($str,$arr) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief provide psuedo random token (string) consisting entirely of US-ASCII letters/numbers
|
||||
* and with possibly variable length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function new_token($minlen = 36, $maxlen = 48) {
|
||||
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
|
||||
$str = EMPTY_STR;
|
||||
|
||||
$len = (($minlen === $maxlen) ? $minlen : mt_rand($minlen, $maxlen));
|
||||
|
||||
for ($a = 0; $a < $len; $a++) {
|
||||
$str .= $chars[mt_rand(0, 62)];
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generate a random v4 UUID.
|
||||
*
|
||||
|
||||
@@ -37,7 +37,7 @@ function is_matrix_url($url) {
|
||||
* @return string
|
||||
*/
|
||||
function zid($s, $address = '') {
|
||||
if (! strlen($s) || strpos($s,'zid='))
|
||||
if (!$s || strpos($s,'zid='))
|
||||
return $s;
|
||||
|
||||
$m = parse_url($s);
|
||||
|
||||
@@ -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` (
|
||||
@@ -146,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`),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user