aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2025-04-29 09:52:30 +0000
committerMario <mario@mariovavti.com>2025-04-29 09:52:30 +0000
commitb6f0fe758303e1446f45d6367075b99ec77d8af3 (patch)
treebdc86032ffd0d999f0591e63a1f2ad7726606ad9
parent377fe32795ab9d1bbf099312468a42f2c038e692 (diff)
downloadvolse-hubzilla-b6f0fe758303e1446f45d6367075b99ec77d8af3.tar.gz
volse-hubzilla-b6f0fe758303e1446f45d6367075b99ec77d8af3.tar.bz2
volse-hubzilla-b6f0fe758303e1446f45d6367075b99ec77d8af3.zip
refactor with permissions
-rw-r--r--Zotlabs/Lib/ThreadItem.php1
-rw-r--r--Zotlabs/Module/Request.php72
-rw-r--r--boot.php2
-rw-r--r--include/items.php71
-rw-r--r--include/security.php20
-rw-r--r--view/js/main.js46
-rw-r--r--view/tpl/conv_item.tpl6
-rw-r--r--view/tpl/notifications_widget.tpl2
8 files changed, 150 insertions, 70 deletions
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index ac9da29a3..f41ab7705 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -382,6 +382,7 @@ class ThreadItem {
'folders' => $body['folders'],
'text' => strip_tags($body['html']),
'id' => $this->get_id(),
+ 'parent' => intval($item['parent']),
'mid' => $midb64,
'mids' => $json_mids,
'parent' => $item['parent'],
diff --git a/Zotlabs/Module/Request.php b/Zotlabs/Module/Request.php
index 660537812..811350205 100644
--- a/Zotlabs/Module/Request.php
+++ b/Zotlabs/Module/Request.php
@@ -28,13 +28,17 @@ class Request extends Controller
private function processSubthreadRequest() : string
{
$mid = $_GET['mid'];
- $items = items_by_thr_parent($mid);
+ $parent = intval($_GET['parent']);
+ $module = strip_tags($_GET['module']);
+
+ $items = items_by_thr_parent($mid, $parent);
xchan_query($items,true,(($sys_item) ? local_channel() : 0));
+
$items = fetch_post_tags($items,true);
// $items = conv_sort($items,'created');
- $ret['html'] = conversation($items, 'network', true, 'r_preview');
+ $ret['html'] = conversation($items, $module, true, 'r_preview');
json_return_and_die($ret);
}
@@ -43,7 +47,7 @@ class Request extends Controller
{
if (!local_channel()) {
- killme();
+ // killme();
}
if ($_GET['verb'] === 'comment') {
@@ -56,28 +60,60 @@ class Request extends Controller
killme();
}
+ $parent = intval($_GET['parent']);
$mid = strip_tags($_GET['mid']);
- $hash = get_observer_hash();
+
+ $observer_hash = get_observer_hash();
$item_normal = item_normal();
- $r = q("SELECT xchan_hash, xchan_name as name, xchan_url as url, xchan_photo_s as photo FROM item
- LEFT JOIN xchan ON author_xchan = xchan_hash
- WHERE uid = %d
- AND thr_parent = '%s'
- AND verb = '%s'
- AND item_thread_top = 0
- $item_normal",
- intval(local_channel()),
- dbesc($mid),
- dbesc($verb)
- );
+ if (local_channel()) {
+ $r = q("SELECT xchan_hash, xchan_name as name, xchan_url as url, xchan_photo_s as photo FROM item
+ LEFT JOIN xchan ON author_xchan = xchan_hash
+ WHERE uid = %d
+ AND thr_parent = '%s'
+ AND verb = '%s'
+ AND item_thread_top = 0
+ $item_normal
+ ORDER BY item.created",
+ intval(local_channel()),
+ dbesc($mid),
+ dbesc($verb)
+ );
+ }
+
+ if (!$r) {
+ $sys = get_sys_channel();
+ $sql_extra = item_permissions_sql(0, $observer_hash);
+
+ $r = q("SELECT xchan_hash, xchan_name as name, xchan_url as url, xchan_photo_s as photo FROM item
+ LEFT JOIN xchan ON author_xchan = xchan_hash
+ WHERE
+ -- This covers /channel/name -- This covers /pubstream
+ ((item.thr_parent = '%s' $sql_extra) OR (item.thr_parent = '%s' AND item.uid = %d))
+ AND parent = %d
+ AND verb = '%s'
+ AND item_thread_top = 0
+ $item_normal
+ ORDER BY item.created",
+ dbesc($mid),
+ dbesc($mid),
+ intval($sys['channel_id']),
+ intval($parent),
+ dbesc($verb)
+ );
+ }
$ret = [
- 'result' => $r,
- 'action' => (($verb === 'Announce') ? 'jotShare' : 'dolike'),
- 'action_label' => ((find_xchan_in_array($hash, $r)) ? t('- Remove yours') : t('+ Add yours'))
+ 'result' => $r
];
+
+ // TODO: check permission to like
+ if ($observer_hash) {
+ $ret['action'] = (($verb === 'Announce') ? 'jotShare' : 'dolike');
+ $ret['action_label'] = ((find_xchan_in_array($observer_hash, $r)) ? t('- Remove yours') : t('+ Add yours'));
+ }
+
json_return_and_die($ret);
}
diff --git a/boot.php b/boot.php
index 8929be5e9..dc7740e11 100644
--- a/boot.php
+++ b/boot.php
@@ -69,7 +69,7 @@ require_once('include/security.php');
define('PLATFORM_NAME', 'hubzilla');
-define('STD_VERSION', '10.3.5+lazy');
+define('STD_VERSION', '10.3.6+lazy');
define('ZOT_REVISION', '6.0');
define('DB_UPDATE_VERSION', 1263);
diff --git a/include/items.php b/include/items.php
index 617518a6b..87921b2b2 100644
--- a/include/items.php
+++ b/include/items.php
@@ -5431,29 +5431,62 @@ function items_by_parent_ids($ids, $sql_extra = '') {
return $ret;
}
-function items_by_thr_parent($mid, $sql_extra = '') {
+function items_by_thr_parent($mid, $parent, $sql_extra = '') {
$item_normal = item_normal();
$item_normal_c = str_replace('item.', 'c.', $item_normal);
$activity_sql = item_activity_sql('c');
- $ret = q(
- "SELECT item.*,
- $activity_sql
- FROM item
- LEFT JOIN item c
- ON c.parent = item.parent
- AND c.item_thread_top = 0
- AND c.thr_parent = item.mid
- $item_normal_c
- WHERE item.thr_parent = '%s'
- AND item.uid = %d
- AND item.verb NOT IN ('Like', 'Dislike', 'Announce')
- AND item.item_thread_top = 0
- $item_normal
- GROUP BY item.id",
- dbesc($mid),
- intval(local_channel())
- );
+
+ if (local_channel()) {
+ $ret = q(
+ "SELECT item.*,
+ $activity_sql
+ FROM item
+ LEFT JOIN item c
+ ON c.parent = item.parent
+ AND c.item_thread_top = 0
+ AND c.thr_parent = item.mid
+ $item_normal_c
+ WHERE item.thr_parent = '%s'
+ AND item.uid = %d
+ AND item.verb NOT IN ('Like', 'Dislike', 'Announce')
+ AND item.item_thread_top = 0
+ $item_normal
+ GROUP BY item.id
+ ORDER BY item.created",
+ dbesc($mid),
+ intval(local_channel())
+ );
+ }
+
+ if (!$ret) {
+ $sys = get_sys_channel();
+ $observer_hash = get_observer_hash();
+ $sql_extra = item_permissions_sql(0, $observer_hash);
+
+ $ret = q(
+ "SELECT item.*,
+ $activity_sql
+ FROM item
+ LEFT JOIN item c ON c.parent = item.parent
+ AND c.item_thread_top = 0
+ AND c.thr_parent = item.mid
+ $item_normal_c
+ WHERE
+ -- This covers /channel/name -- This covers /pubstream
+ ((item.thr_parent = '%s' $sql_extra) OR (item.thr_parent = '%s' AND item.uid = %d))
+ AND item.parent = %d
+ AND item.verb NOT IN ('Like', 'Dislike', 'Announce')
+ AND item.item_thread_top = 0
+ $item_normal
+ GROUP BY item.id
+ ORDER BY item.created",
+ dbesc($mid),
+ dbesc($mid),
+ intval($sys['channel_id']),
+ intval($parent)
+ );
+ }
return $ret;
}
diff --git a/include/security.php b/include/security.php
index 2e0497498..8e13d4195 100644
--- a/include/security.php
+++ b/include/security.php
@@ -432,7 +432,7 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
* default permissions - anonymous user
*/
- $sql = " AND item_private = 0 ";
+ $sql = " AND item.item_private = 0 ";
/**
* Profile owner - everything is visible
@@ -492,10 +492,10 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
$regexop = db_getfunc('REGEXP');
$sql = sprintf(
- " AND ( author_xchan = '%s' OR owner_xchan = '%s' OR
- (( NOT (deny_cid $regexop '%s' OR deny_gid $regexop '%s')
- AND ( allow_cid $regexop '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 ))
- )) OR ( item_private = 1 $scope ))
+ " AND ( item.author_xchan = '%s' OR item.owner_xchan = '%s' OR
+ (( NOT (item.deny_cid $regexop '%s' OR item.deny_gid $regexop '%s')
+ AND ( item.allow_cid $regexop '%s' OR item.allow_gid $regexop '%s' OR ( item.allow_cid = '' AND item.allow_gid = '' AND item.item_private = 0 ))
+ )) OR ( item.item_private = 1 $scope ))
",
dbesc($observer),
dbesc($observer),
@@ -518,11 +518,11 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
function scopes_sql($uid, $observer) {
- $str = " and ( public_policy = 'authenticated' ";
+ $str = " and ( item.public_policy = 'authenticated' ";
if (!is_foreigner($observer))
- $str .= " or public_policy = 'network: red' ";
+ $str .= " or item.public_policy = 'network: red' ";
if (local_channel())
- $str .= " or public_policy = 'site: " . App::get_hostname() . "' ";
+ $str .= " or item.public_policy = 'site: " . App::get_hostname() . "' ";
$ab = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($observer),
@@ -531,8 +531,8 @@ function scopes_sql($uid, $observer) {
if (!$ab)
return $str . " ) ";
if ($ab[0]['abook_pending'])
- $str .= " or public_policy = 'any connections' ";
- $str .= " or public_policy = 'contacts' ) ";
+ $str .= " or item.public_policy = 'any connections' ";
+ $str .= " or item.public_policy = 'contacts' ) ";
return $str;
}
diff --git a/view/js/main.js b/view/js/main.js
index b54879e40..c927e8521 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -1266,40 +1266,51 @@ function justifyPhotosAjax(id) {
$('#' + id).justifiedGallery('norewind').on('jg.complete', function(e){ justifiedGalleryActive = false; });
}
-function request(id, mid, verb) {
+function request(id, mid, verb, parent) {
+
+ const loading = document.getElementById('like-rotator-' + id);
+ loading.style.display = 'block';
if (verb === 'comment') {
- fetch('/request?verb=' + verb + '&mid=' + mid)
+
+ document.querySelectorAll('.thread-wrapper.item-highlight').forEach(el => {
+ el.classList.remove('item-highlight');
+ });
+
+ document.getElementById('thread-wrapper-' + id).classList.add('item-highlight');
+
+ fetch('/request?verb=' + verb + '&mid=' + mid + '&parent=' + parent + '&module=' + module)
.then(response => response.json())
.then(obj => {
injectWithAnimation('sub-thread-wrapper-' + id, obj.html);
updateRelativeTime('.autotime');
+ loading.style.display = 'none';
})
.catch(error => {
console.error('Error fetching data:', error);
});
}
else {
- const modal = new bootstrap.Modal('#reactions');
- modal.show();
-
- const modal_content = document.getElementById('reactions_body');
- modal_content.innerHTML = 'Loading...';
-
- const modal_title = document.getElementById('reactions_title');
- modal_title.innerHTML = verb;
-
- const modal_action = document.getElementById('reactions_action');
- modal_action.innerHTML = '';
-
- fetch('/request?verb=' + verb + '&mid=' + mid)
+ fetch('/request?verb=' + verb + '&mid=' + mid + '&parent=' + parent)
.then(response => response.json())
.then(obj => {
+ const modal = new bootstrap.Modal('#reactions');
+ const modal_content = document.getElementById('reactions_body');
+ const modal_title = document.getElementById('reactions_title');
+ const modal_action = document.getElementById('reactions_action');
+ modal_action.style.display = 'none';
+ modal_title.innerHTML = verb;
modal_content.innerHTML = '';
- modal_action.innerHTML = '<a href="#" onclick="' + obj.action + '(' + id + ',\'' + verb + '\'); return false;">' + obj.action_label + '</a>';
+ if (obj.action) {
+ modal_action.innerHTML = '<a href="#" onclick="' + obj.action + '(' + id + ',\'' + verb + '\'); return false;">' + obj.action_label + '</a>';
+ modal_action.style.display = 'block';
+ }
obj.result.forEach(e => {
modal_content.innerHTML += '<a href="' + e.url + '" class="list-group-item list-group-item-action border-0"><img src="' + e.photo + '" class="menu-img-1" loading="lazy">&nbsp;' + e.name + '</a>';
});
+
+ modal.show();
+ loading.style.display = 'none';
})
.catch(error => {
console.error('Error fetching data:', error);
@@ -1328,7 +1339,8 @@ function injectWithAnimation(container, html) {
], {
duration: 300,
delay: i * 50,
- fill: 'both'
+ fill: 'both',
+ easing: 'ease-out'
});
});
}
diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl
index 87d2d69d4..47983eb1b 100644
--- a/view/tpl/conv_item.tpl
+++ b/view/tpl/conv_item.tpl
@@ -110,13 +110,11 @@
<div class="p-2 wall-item-tools d-flex justify-content-between">
<div class="wall-item-tools-left hstack gap-1" id="wall-item-tools-left-{{$item.id}}">
{{foreach $item.responses as $verb=>$response}}
- {{if $item.reactions_allowed || (!$item.reactions_allowed && $response.count)}}
{{if !($verb == 'comment' && $item.toplevel)}}
- <button type="button" title="{{$response.count}} {{$response.button.label}}" class="btn btn-sm btn-link{{if !$item.observer_activity.$verb}} link-secondary{{/if}} wall-item-{{$response.button.class}}"{{if $item.reactions_allowed}} onclick="request({{$item.id}}, '{{$item.rawmid}}', '{{$verb}}'); return false;"{{/if}} id="wall-item-{{$verb}}-{{$item.id}}">
+ <button type="button" title="{{$response.count}} {{$response.button.label}}" class="btn btn-sm btn-link{{if !$item.observer_activity.$verb}} link-secondary{{/if}} wall-item-{{$response.button.class}}" onclick="request({{$item.id}}, '{{$item.rawmid}}', '{{$verb}}', {{$item.parent}}); return false;" id="wall-item-{{$verb}}-{{$item.id}}">
<i class="bi bi-{{$response.button.icon}} generic-icons"></i>{{if $response.count}}<span style="display: inline-block; margin-top: -.25rem;" class="align-top">{{$response.count}}</span>{{/if}}
</button>
{{/if}}
- {{/if}}
{{/foreach}}
{{if $item.toplevel && $item.emojis && $item.reactions}}
<div class="">
@@ -220,10 +218,10 @@
</div>
</div>
</div>
+ <div id="sub-thread-wrapper-{{$item.id}}"></div>
{{if $item.toplevel}}
{{foreach $item.children as $child}}
{{include file="{{$child.template}}" item=$child}}
- <div id="sub-thread-wrapper-{{$child.id}}"></div>
{{/foreach}}
{{/if}}
{{if $item.comment}}
diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl
index 2156c1f4c..0a64abd32 100644
--- a/view/tpl/notifications_widget.tpl
+++ b/view/tpl/notifications_widget.tpl
@@ -631,7 +631,7 @@
noNotifications.style.display = 'none';
notifications.style.display = 'block';
} else {
- notificationsBtn.style.opacity = 0.5;
+ if (notificationsBtn) notificationsBtn.style.opacity = 0.5;
if (navbarCollapse) navbarCollapse.classList.remove('show');
noNotifications.style.display = 'block';
notifications.style.display = 'none';