mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c8da6ce36 | ||
|
|
e19a050b92 | ||
|
|
546c4fcad2 | ||
|
|
2782b6d724 | ||
|
|
324b281813 | ||
|
|
69a23c604d | ||
|
|
9b13055dfe | ||
|
|
06afd8a375 | ||
|
|
6f027544d6 | ||
|
|
ebab5ff281 | ||
|
|
5fb6e5d6f7 | ||
|
|
5a84ffdcda | ||
|
|
ad993645be | ||
|
|
0701cde239 | ||
|
|
a136c288d5 | ||
|
|
1624a2620a | ||
|
|
f4769d0f04 | ||
|
|
c8e30a00e2 | ||
|
|
169c971cb1 | ||
|
|
51745d3652 | ||
|
|
3ebbb91ae9 | ||
|
|
762d402dea | ||
|
|
051cef79fc | ||
|
|
b05a440f03 | ||
|
|
9bb4988eda | ||
|
|
f66f0e398b | ||
|
|
49cb73c8c7 | ||
|
|
2a00bd9a28 | ||
|
|
553b3f6faa | ||
|
|
2980827925 | ||
|
|
45a78dcbc0 | ||
|
|
5813b65aed | ||
|
|
f8acd1d3a5 | ||
|
|
c9ebb23b69 | ||
|
|
bc998eacd0 | ||
|
|
648979467a | ||
|
|
5c0ff6f584 |
42
CHANGELOG
42
CHANGELOG
@@ -1,3 +1,45 @@
|
||||
Hubzilla 10.0.8 (2025-02-01)
|
||||
- Fix duplicating terms/iconfig in addToCollectionAndSync()
|
||||
- Refactor Daemon/Importdoc for better SQL performance when looking up outdated entries
|
||||
- Tweak SQL in mod sse_bs for possible performance improvements
|
||||
- Fix PHP warnings
|
||||
- Do not run post_local hook on add activities in pubcrawl addon
|
||||
- Do not run post_local hook on add activities in diaspora addon
|
||||
- Remove old rawmsg/fields before storing new rawmsg in pubcrawl addon
|
||||
- Fix retractions in diaspora addon
|
||||
|
||||
|
||||
Hubzilla 10.0.7 (2025-01-22)
|
||||
- Fix ownership check in consume_feed()
|
||||
- Fix toast() if notification contains non-ascii characters
|
||||
- Fix regression in notifications filter
|
||||
|
||||
|
||||
Hubzilla 10.0.6 (2025-01-05)
|
||||
- Fix entries where primary location data is not complete not dismissed early
|
||||
- Fix query to cleanup outdated doc entries called multiple times
|
||||
- Fix query to cleanup outdated doc entries
|
||||
|
||||
|
||||
Hubzilla 10.0.5 (2024-12-29)
|
||||
- Fix another instance of drop_item() not having permission to drop items
|
||||
|
||||
|
||||
Hubzilla 10.0.4 (2024-12-26)
|
||||
- Fix missing argument name
|
||||
|
||||
|
||||
Hubzilla 10.0.3 (2024-12-26)
|
||||
- Fix regression in Daemon/Channel_purge which could cause a possible infinite loop
|
||||
- Fix regression in Daemon/Expire which could cause a infinite loop
|
||||
|
||||
|
||||
Hubzilla 10.0.2 (2024-12-25)
|
||||
- Hotfix comment out Daemon/Expire
|
||||
- Fix zid parameter allowed to override an existing remote login
|
||||
- Slightly improved imagesLoaded()
|
||||
|
||||
|
||||
Hubzilla 10.0.1 (2024-12-22)
|
||||
- Revert removing of openid library
|
||||
- Fix SQL query in Daemon/Importdoc
|
||||
|
||||
@@ -24,7 +24,7 @@ class Channel_purge {
|
||||
);
|
||||
if ($r) {
|
||||
foreach ($r as $rv) {
|
||||
drop_item($rv['id']);
|
||||
drop_item($rv['id'], uid: $channel_id);
|
||||
}
|
||||
}
|
||||
} while ($r);
|
||||
|
||||
@@ -23,13 +23,13 @@ class Expire {
|
||||
|
||||
// perform final cleanup on previously delete items
|
||||
|
||||
$r = q("select id from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s",
|
||||
$r = q("select id, uid from item where item_deleted = 1 and item_pending_remove = 0 and changed < %s - INTERVAL %s",
|
||||
db_utcnow(),
|
||||
db_quoteinterval('10 DAY')
|
||||
);
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
drop_item($rr['id'], DROPITEM_PHASE2);
|
||||
drop_item($rr['id'], DROPITEM_PHASE2, uid: $rr['uid']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,21 @@ class Importdoc {
|
||||
|
||||
self::update_docs_dir('doc/*');
|
||||
|
||||
$sys = get_sys_channel();
|
||||
|
||||
// remove old files that weren't updated (indicates they were most likely deleted).
|
||||
$i = q("select id from item where uid = %d and item_type = 5 and edited < %s - INTERVAL %s",
|
||||
intval($sys['channel_id']),
|
||||
db_utcnow(),
|
||||
db_quoteinterval('14 DAY')
|
||||
);
|
||||
|
||||
if ($i) {
|
||||
foreach ($i as $iv) {
|
||||
drop_item($iv['id'], uid: $sys['channel_id']);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
@@ -41,18 +56,6 @@ class Importdoc {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove old files that weren't updated (indicates they were most likely deleted).
|
||||
$i = q("select * from item where item_type = 5 and edited < %s - INTERVAL %s",
|
||||
db_utcnow(),
|
||||
db_quoteinterval('14 DAY', true)
|
||||
);
|
||||
|
||||
if ($i) {
|
||||
foreach ($i as $iv) {
|
||||
drop_item($iv['id'], DROPITEM_NORMAL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -655,6 +655,11 @@ class Libzot {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if (empty($arr['primary_location']['address'])) {
|
||||
logger('Empty primary location address: ' . print_r($arr, true), LOGGER_DEBUG);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hooks import_xchan
|
||||
* Called when processing the result of zot_finger() to store the result
|
||||
@@ -1556,7 +1561,7 @@ class Libzot {
|
||||
|
||||
$conversation_operation = $is_collection_operation && isset($arr['target']['attributedTo']);
|
||||
|
||||
if (str_contains($arr['tgt_type'], 'Collection') && !$relay && !$conversation_operation) {
|
||||
if (isset($arr['tgt_type']) && str_contains($arr['tgt_type'], 'Collection') && !$relay && !$conversation_operation) {
|
||||
$DR->update('not a collection activity');
|
||||
$result[] = $DR->get();
|
||||
continue;
|
||||
|
||||
@@ -207,7 +207,7 @@ class Sse_bs extends Controller {
|
||||
$item_normal
|
||||
$sql_extra
|
||||
$sql_extra2
|
||||
ORDER BY created DESC LIMIT $limit OFFSET $offset",
|
||||
ORDER BY created DESC, received DESC LIMIT $limit OFFSET $offset",
|
||||
intval(self::$uid),
|
||||
dbescdate($_SESSION['sse_loadtime']),
|
||||
dbesc(self::$ob_hash)
|
||||
@@ -290,7 +290,7 @@ class Sse_bs extends Controller {
|
||||
$item_normal
|
||||
$sql_extra
|
||||
$sql_extra2
|
||||
ORDER BY created DESC LIMIT $limit OFFSET $offset",
|
||||
ORDER BY created DESC, received DESC LIMIT $limit OFFSET $offset",
|
||||
intval(self::$uid),
|
||||
dbescdate($_SESSION['sse_loadtime']),
|
||||
dbesc(self::$ob_hash)
|
||||
@@ -373,7 +373,7 @@ class Sse_bs extends Controller {
|
||||
$item_normal
|
||||
$sql_extra
|
||||
$sql_extra2
|
||||
ORDER BY created DESC LIMIT $limit OFFSET $offset",
|
||||
ORDER BY created DESC, received DESC LIMIT $limit OFFSET $offset",
|
||||
intval(self::$uid),
|
||||
dbescdate($_SESSION['sse_loadtime']),
|
||||
dbesc(self::$ob_hash)
|
||||
@@ -481,7 +481,7 @@ class Sse_bs extends Controller {
|
||||
$sql_extra
|
||||
$sql_extra2
|
||||
$sql_extra3
|
||||
ORDER BY created DESC LIMIT $limit OFFSET $offset",
|
||||
ORDER BY created DESC, received DESC LIMIT $limit OFFSET $offset",
|
||||
dbescdate($_SESSION['sse_loadtime']),
|
||||
dbesc(self::$ob_hash),
|
||||
dbescdate($_SESSION['last_login_date'] ?? $_SESSION['static_loadtime'])
|
||||
@@ -679,7 +679,7 @@ class Sse_bs extends Controller {
|
||||
AND author_xchan != '%s'
|
||||
AND item_unseen = 1
|
||||
$item_normal
|
||||
ORDER BY created DESC",
|
||||
ORDER BY created DESC, received DESC",
|
||||
dbesc(ACTIVITY_POST),
|
||||
intval(self::$uid),
|
||||
dbesc(self::$ob_hash)
|
||||
|
||||
@@ -61,7 +61,7 @@ class WebServer {
|
||||
if (x($_GET,'zid') && $installed) {
|
||||
\App::$query_string = strip_zids(\App::$query_string);
|
||||
if(! local_channel()) {
|
||||
if (!isset($_SESSION['my_address']) || $_SESSION['my_address'] != $_GET['zid']) {
|
||||
if (!isset($_SESSION['my_address'])) {
|
||||
$_SESSION['my_address'] = Text::escape_tags($_GET['zid']);
|
||||
$_SESSION['authenticated'] = 0;
|
||||
}
|
||||
|
||||
2
boot.php
2
boot.php
@@ -66,7 +66,7 @@ require_once('include/security.php');
|
||||
|
||||
|
||||
define('PLATFORM_NAME', 'hubzilla');
|
||||
define('STD_VERSION', '10.0.1');
|
||||
define('STD_VERSION', '10.0.8');
|
||||
define('ZOT_REVISION', '6.0');
|
||||
|
||||
define('DB_UPDATE_VERSION', 1263);
|
||||
|
||||
@@ -513,7 +513,7 @@ function remove_abook_items($channel_id, $xchan_hash) {
|
||||
continue;
|
||||
}
|
||||
|
||||
drop_item($rr['id']);
|
||||
drop_item($rr['id'], uid: $channel_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1173,12 +1173,16 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
intval($importer['channel_id'])
|
||||
);
|
||||
|
||||
|
||||
// Update content if 'updated' changes
|
||||
|
||||
if($r) {
|
||||
if(activity_match($datarray['verb'], ['Delete', ACTIVITY_DELETE])
|
||||
&& $datarray['author_xchan'] === $r[0]['author_xchan']) {
|
||||
if ($r) {
|
||||
// Check ownership
|
||||
if ($datarray['author_xchan'] !== $r[0]['author_xchan']) {
|
||||
logger('stored item author is not imported item author', LOGGER_DEBUG);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (activity_match($datarray['verb'], ['Delete', ACTIVITY_DELETE])) {
|
||||
if(! intval($r[0]['item_deleted'])) {
|
||||
logger('deleting item ' . $r[0]['id'] . ' mid=' . $datarray['mid'], LOGGER_DEBUG);
|
||||
drop_item($r[0]['id']);
|
||||
@@ -1444,12 +1448,17 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
|
||||
// Update content if 'updated' changes
|
||||
|
||||
if($r) {
|
||||
if(isset($datarray['verb']) && activity_match($datarray['verb'], ['Delete', ACTIVITY_DELETE])
|
||||
&& isset($datarray['author_xchan']) && $datarray['author_xchan'] === $r[0]['author_xchan']) {
|
||||
if ($r) {
|
||||
// Check ownership
|
||||
if ($datarray['author_xchan'] !== $r[0]['author_xchan']) {
|
||||
logger('stored item author is not imported item author', LOGGER_DEBUG);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($datarray['verb']) && activity_match($datarray['verb'], ['Delete', ACTIVITY_DELETE])) {
|
||||
if(! intval($r[0]['item_deleted'])) {
|
||||
logger('deleting item ' . $r[0]['id'] . ' mid=' . $datarray['mid'], LOGGER_DEBUG);
|
||||
drop_item($r[0]['id']);
|
||||
drop_item($r[0]['id'], uid: $importer['channel_id']);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3861,7 +3861,7 @@ function item_expire($uid,$days,$comment_days = 7) {
|
||||
|
||||
if ($r) {
|
||||
foreach ($r as $item) {
|
||||
drop_item($item['id'], expire: true);
|
||||
drop_item($item['id'], uid: $uid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3922,7 +3922,7 @@ function drop_item($id, $stage = DROPITEM_NORMAL, $force = false, $uid = 0, $obs
|
||||
$ok_to_delete = true;
|
||||
}
|
||||
|
||||
// remote delete when nobody is authenticated (called from Libzot)
|
||||
// remote delete when nobody is authenticated (called from Libzot and Daemons)
|
||||
if ($uid && intval($uid) === intval($item['uid'])) {
|
||||
$ok_to_delete = true;
|
||||
}
|
||||
@@ -5293,7 +5293,8 @@ function addToCollectionAndSync($ret) {
|
||||
}
|
||||
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items);
|
||||
// TODO: fetch_post_tags() will add term and iconfig twice if called twice and it looks like they are already added here
|
||||
// $items = fetch_post_tags($items);
|
||||
$sync_items = [];
|
||||
$sync_items[] = encode_item($items[0], true);
|
||||
|
||||
|
||||
@@ -143,6 +143,10 @@ function oembed_fetch_url($embedurl){
|
||||
|
||||
$furl = ((local_channel() && $zrl) ? zid($embedurl) : $embedurl);
|
||||
|
||||
if (empty($furl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if($action !== 'block' && (! Config::Get('system','oembed_cache_disable'))) {
|
||||
$txt = Cache::get('[' . App::$videowidth . '] ' . $furl);
|
||||
}
|
||||
|
||||
@@ -793,48 +793,51 @@ function imagesLoaded(elements, callback) {
|
||||
let loadedCount = 0;
|
||||
let totalImages = 0;
|
||||
let timeoutId;
|
||||
let timeout = 10000;
|
||||
let processed = [];
|
||||
const timeout = 10000;
|
||||
const processed = new Set(); // Use a Set for efficient lookup
|
||||
|
||||
// Helper function to extract img elements from an HTML string
|
||||
function extractImagesFromHtml(htmlString) {
|
||||
let tempDiv = document.createElement('div');
|
||||
const tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = htmlString;
|
||||
return tempDiv.querySelectorAll('.wall-item-body img, .wall-photo-item img');
|
||||
}
|
||||
|
||||
function checkComplete(src) {
|
||||
// Track processed images to not count images multiple times if load event is emited from multiple sources
|
||||
if (processed.includes(src)) {
|
||||
return;
|
||||
}
|
||||
// Skip processing if image has already been processed
|
||||
if (processed.has(src)) return;
|
||||
|
||||
processed.push(src);
|
||||
processed.add(src);
|
||||
loadedCount++;
|
||||
|
||||
document.getElementById('image_counter').innerHTML = Math.round((loadedCount * 100) / totalImages) + '%';
|
||||
// Update progress
|
||||
const progress = Math.round((loadedCount * 100) / totalImages);
|
||||
document.getElementById('image_counter').innerText = `${progress}%`;
|
||||
|
||||
// If all images are loaded, trigger the callback
|
||||
if (loadedCount === totalImages) {
|
||||
document.getElementById('image_counter').innerHTML = '';
|
||||
document.getElementById('image_counter').innerText = '';
|
||||
clearTimeout(timeoutId);
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
// If the elements is an HTML string, convert it to img elements
|
||||
// Convert HTML string to img elements if necessary
|
||||
if (typeof elements === 'string') {
|
||||
elements = extractImagesFromHtml(elements);
|
||||
}
|
||||
|
||||
// If elements is not a valid array-like object, or is empty, exit early
|
||||
// Exit early if there are no images to load
|
||||
if (!elements || elements.length === 0) {
|
||||
callback(); // No images to load, immediately call the callback
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
let images = Array.from(elements)
|
||||
.filter(element => element.tagName && element.tagName.toLowerCase() === 'img' && element.src)
|
||||
// Filter valid image elements (only img with src attribute)
|
||||
const images = Array.from(elements)
|
||||
.filter((element) => element.tagName.toLowerCase() === 'img' && element.src)
|
||||
.filter((element, index, self) =>
|
||||
index === self.findIndex(e => e.src === element.src)
|
||||
index === self.findIndex(e => e.src === element.src) // Avoid duplicates
|
||||
);
|
||||
|
||||
// If no images are found, call the callback immediately
|
||||
@@ -843,29 +846,24 @@ function imagesLoaded(elements, callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set timeout
|
||||
totalImages = images.length;
|
||||
|
||||
// Set timeout for the loading process
|
||||
timeoutId = setTimeout(() => {
|
||||
console.warn(`Image loading timed out after ${timeout}ms`);
|
||||
callback(false);
|
||||
}, timeout);
|
||||
|
||||
totalImages = images.length;
|
||||
|
||||
// Iterate through images to add load and error event listeners
|
||||
images.forEach((img) => {
|
||||
// Otherwise it will not load until visible
|
||||
img.loading = 'eager';
|
||||
img.loading = 'eager'; // Preload the image
|
||||
|
||||
if (img.complete && img.naturalHeight !== 0) {
|
||||
// Image is already loaded successfully
|
||||
//console.log(`Image cached: ${img.src}`);
|
||||
if (img.complete && img.naturalHeight > 0) {
|
||||
// Image is already loaded, handle immediately
|
||||
checkComplete(img.src);
|
||||
} else {
|
||||
// Add event listeners for load and error events
|
||||
img.addEventListener('load', () => {
|
||||
//console.log(`Image loaded: ${img.src}`);
|
||||
checkComplete(img.src);
|
||||
});
|
||||
|
||||
img.addEventListener('load', () => checkComplete(img.src));
|
||||
img.addEventListener('error', () => {
|
||||
console.log(`Image failed to load: ${img.src}`);
|
||||
checkComplete(img.src);
|
||||
@@ -874,7 +872,6 @@ function imagesLoaded(elements, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function updateRelativeTime(selector) {
|
||||
// Get all elements with the given selector
|
||||
const timeElements = document.querySelectorAll(selector);
|
||||
@@ -1799,7 +1796,7 @@ function toggleAside() {
|
||||
}
|
||||
|
||||
function toast(string, severity) {
|
||||
let id = btoa(string);
|
||||
let id = bin2hex(string);
|
||||
let container = document.getElementById('toast-container');
|
||||
let toast = document.getElementById(id);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* * Description: Hubzilla standard theme
|
||||
* * Version: 2.2
|
||||
* * MinVersion: 8.9
|
||||
* * MaxVersion: 10.0
|
||||
* * MaxVersion: 11.0
|
||||
* * Author: Fabrixxm
|
||||
* * Maintainer: Mike Macgirvin
|
||||
* * Maintainer: Mario Vavti
|
||||
|
||||
@@ -546,7 +546,7 @@
|
||||
}
|
||||
|
||||
// Filter thread_top notifications if the filter is active
|
||||
let filterThreadTop = document.getElementById('cn-' + notifyType + '-input');
|
||||
let filterThreadTop = document.getElementById('tt-' + notifyType + '-only');
|
||||
if (filterThreadTop && filterThreadTop.classList.contains('active')) {
|
||||
let notifications = notify_menu.querySelectorAll('[data-thread_top="false"]');
|
||||
notifications.forEach(notification => notification.classList.add('tt-filter-active'));
|
||||
|
||||
Reference in New Issue
Block a user