Restructured item insert
This commit is contained in:
+364
-382
@@ -1333,7 +1333,269 @@ class Item
|
||||
}
|
||||
}
|
||||
|
||||
public static function insert($item, $force_parent = false, $notify = false, $dontcache = false)
|
||||
private static function isDuplicate($item)
|
||||
{
|
||||
// Checking if there is already an item with the same guid
|
||||
$condition = ['guid' => $item['guid'], 'network' => $item['network'], 'uid' => $item['uid']];
|
||||
if (self::exists($condition)) {
|
||||
Logger::notice('Found already existing item', [
|
||||
'guid' => $item['guid'],
|
||||
'uid' => $item['uid'],
|
||||
'network' => $item['network']
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
|
||||
$condition = ["`uri` = ? AND `network` IN (?, ?) AND `uid` = ?",
|
||||
$item['uri'], $item['network'], Protocol::DFRN, $item['uid']];
|
||||
if (self::exists($condition)) {
|
||||
Logger::notice('duplicated item with the same uri found.', $item);
|
||||
return true;
|
||||
}
|
||||
|
||||
// On Friendica and Diaspora the GUID is unique
|
||||
if (in_array($item['network'], [Protocol::DFRN, Protocol::DIASPORA])) {
|
||||
$condition = ['guid' => $item['guid'], 'uid' => $item['uid']];
|
||||
if (self::exists($condition)) {
|
||||
Logger::notice('duplicated item with the same guid found.', $item);
|
||||
return true;
|
||||
}
|
||||
} elseif ($item['network'] == Protocol::OSTATUS) {
|
||||
// Check for an existing post with the same content. There seems to be a problem with OStatus.
|
||||
$condition = ["`body` = ? AND `network` = ? AND `created` = ? AND `contact-id` = ? AND `uid` = ?",
|
||||
$item['body'], $item['network'], $item['created'], $item['contact-id'], $item['uid']];
|
||||
if (self::exists($condition)) {
|
||||
Logger::notice('duplicated item with the same body found.', $item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for already added items.
|
||||
* There is a timing issue here that sometimes creates double postings.
|
||||
* An unique index would help - but the limitations of MySQL (maximum size of index values) prevent this.
|
||||
*/
|
||||
if (($item["uid"] == 0) && self::exists(['uri' => trim($item['uri']), 'uid' => 0])) {
|
||||
Logger::notice('Global item already stored.', ['uri' => $item['uri'], 'network' => $item['network']]);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function validItem($item)
|
||||
{
|
||||
// When there is no content then we don't post it
|
||||
if ($item['body'].$item['title'] == '') {
|
||||
Logger::notice('No body, no title.');
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for create date and expire time
|
||||
$expire_interval = DI::config()->get('system', 'dbclean-expire-days', 0);
|
||||
|
||||
$user = DBA::selectFirst('user', ['expire'], ['uid' => $item['uid']]);
|
||||
if (DBA::isResult($user) && ($user['expire'] > 0) && (($user['expire'] < $expire_interval) || ($expire_interval == 0))) {
|
||||
$expire_interval = $user['expire'];
|
||||
}
|
||||
|
||||
if (($expire_interval > 0) && !empty($item['created'])) {
|
||||
$expire_date = time() - ($expire_interval * 86400);
|
||||
$created_date = strtotime($item['created']);
|
||||
if ($created_date < $expire_date) {
|
||||
Logger::notice('Item created before expiration interval.', [
|
||||
'created' => date('c', $created_date),
|
||||
'expired' => date('c', $expire_date),
|
||||
'$item' => $item
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Contact::isBlocked($item['author-id'])) {
|
||||
Logger::notice('Author is blocked node-wide', ['author-link' => $item['author-link'], 'item-uri' => $item['uri']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($item['author-link']) && Network::isUrlBlocked($item['author-link'])) {
|
||||
Logger::notice('Author server is blocked', ['author-link' => $item['author-link'], 'item-uri' => $item['uri']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($item['uid']) && Contact::isBlockedByUser($item['author-id'], $item['uid'])) {
|
||||
Logger::notice('Author is blocked by user', ['author-link' => $item['author-link'], 'uid' => $item['uid'], 'item-uri' => $item['uri']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Contact::isBlocked($item['owner-id'])) {
|
||||
Logger::notice('Owner is blocked node-wide', ['owner-link' => $item['owner-link'], 'item-uri' => $item['uri']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($item['owner-link']) && Network::isUrlBlocked($item['owner-link'])) {
|
||||
Logger::notice('Owner server is blocked', ['owner-link' => $item['owner-link'], 'item-uri' => $item['uri']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($item['uid']) && Contact::isBlockedByUser($item['owner-id'], $item['uid'])) {
|
||||
Logger::notice('Owner is blocked by user', ['owner-link' => $item['owner-link'], 'uid' => $item['uid'], 'item-uri' => $item['uri']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The causer is set during a thread completion, for example because of a reshare. It countains the responsible actor.
|
||||
if (!empty($item['uid']) && !empty($item['causer-id']) && Contact::isBlockedByUser($item['causer-id'], $item['uid'])) {
|
||||
Logger::notice('Causer is blocked by user', ['causer-link' => $item['causer-link'], 'uid' => $item['uid'], 'item-uri' => $item['uri']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($item['uid']) && !empty($item['causer-id']) && ($item['parent-uri'] == $item['uri']) && Contact::isIgnoredByUser($item['causer-id'], $item['uid'])) {
|
||||
Logger::notice('Causer is ignored by user', ['causer-link' => $item['causer-link'], 'uid' => $item['uid'], 'item-uri' => $item['uri']]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($item['verb'] == Activity::FOLLOW) {
|
||||
if (!$item['origin'] && ($item['author-id'] == Contact::getPublicIdByUserId($item['uid']))) {
|
||||
// Our own follow request can be relayed to us. We don't store it to avoid notification chaos.
|
||||
Logger::log("Follow: Don't store not origin follow request from us for " . $item['parent-uri'], Logger::DEBUG);
|
||||
return false;
|
||||
}
|
||||
|
||||
$condition = ['verb' => Activity::FOLLOW, 'uid' => $item['uid'],
|
||||
'parent-uri' => $item['parent-uri'], 'author-id' => $item['author-id']];
|
||||
if (self::exists($condition)) {
|
||||
// It happens that we receive multiple follow requests by the same author - we only store one.
|
||||
Logger::log('Follow: Found existing follow request from author ' . $item['author-id'] . ' for ' . $item['parent-uri'], Logger::DEBUG);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function getDuplicateID($item)
|
||||