diff --git a/src/Model/Contact.php b/src/Model/Contact.php index a6026d6440..7a3731e537 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1328,7 +1328,7 @@ class Contact extends BaseObject // Update the contact in the background if needed but it is called by the frontend if ($update_contact && $no_update && in_array($contact['network'], Protocol::NATIVE_SUPPORT)) { - Worker::add(PRIORITY_LOW, "UpdateContact", $contact_id); + Worker::add(PRIORITY_LOW, "UpdateContact", $contact_id, ($uid == 0 ? 'force' : '')); } if (!$update_contact || $no_update) { @@ -1425,7 +1425,7 @@ class Contact extends BaseObject // Update in the background when we fetched the data solely from the database if ($background_update) { - Worker::add(PRIORITY_LOW, "UpdateContact", $contact_id); + Worker::add(PRIORITY_LOW, "UpdateContact", $contact_id, ($uid == 0 ? 'force' : '')); } // Update the newly created contact from data in the gcontact table @@ -1807,6 +1807,8 @@ class Contact extends BaseObject } } + self::updateAvatar($ret['photo'], $uid, $id, $update || $force); + if (!$update) { return true; } @@ -1814,11 +1816,14 @@ class Contact extends BaseObject $ret['nurl'] = Strings::normaliseLink($ret['url']); $ret['updated'] = DateTimeFormat::utcNow(); - self::updateAvatar($ret['photo'], $uid, $id, true); - unset($ret['photo']); DBA::update('contact', $ret, ['id' => $id]); + // Updating all similar contacts when we are updating the public contact + if (($uid == 0) && in_array($ret['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS])) { + DBA::update('contact', $ret, ['self' => false, 'nurl' => $ret['nurl']]); + } + // Update the corresponding gcontact entry PortableContact::lastUpdated($ret["url"]); diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php index f7377a6e71..8d290698d6 100644 --- a/src/Worker/Cron.php +++ b/src/Worker/Cron.php @@ -117,6 +117,9 @@ class Cron // Poll contacts self::pollContacts($parameter, $generation); + // Update contact information + self::updatePublicContacts(); + Logger::log('cron: end'); Config::set('system', 'last_cron', time()); @@ -124,6 +127,26 @@ class Cron return; } + /** + * @brief Update public contacts + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + private static function updatePublicContacts() { + $count = 0; + $last_updated = DateTimeFormat::utc('now - 1 months'); + $condition = ["`network` IN (?, ?, ?, ?) AND `uid` = ? AND NOT `self` AND `last-update` < ?", + Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, 0, $last_updated]; + + $total = DBA::count('contact', $condition); + $contacts = DBA::select('contact', ['id'], $condition, ['limit' => 1000]); + while ($contact = DBA::fetch($contacts)) { + Worker::add(PRIORITY_LOW, "UpdateContact", $contact['id'], 'force'); + ++$count; + } + Logger::info('Initiated update for public contacts', ['interval' => $count, 'total' => $total]); + DBA::close($contacts); + } + /** * @brief Poll contacts for unreceived messages * diff --git a/src/Worker/UpdateContact.php b/src/Worker/UpdateContact.php index ae3b06b506..7679431fd9 100644 --- a/src/Worker/UpdateContact.php +++ b/src/Worker/UpdateContact.php @@ -13,16 +13,26 @@ use Friendica\Database\DBA; class UpdateContact { - public static function execute($contact_id) + public static function execute($contact_id, $command = '') { - $success = Contact::updateFromProbe($contact_id); - // Update the "updated" field if the contact could be probed. - // We don't do this in the function above, since we don't want to - // update the contact whenever that function is called from anywhere. - if ($success) { - DBA::update('contact', ['updated' => DateTimeFormat::utcNow()], ['id' => $contact_id]); + $force = ($command == "force"); + + $success = Contact::updateFromProbe($contact_id, '', $force); + + Logger::info('Updated from probe', ['id' => $contact_id, 'force' => $force, 'success' => $success]); + + // Update the update date fields only when we are forcing the update + if (!$force) { + return; } - Logger::info('Updated from probe', ['id' => $contact_id, 'success' => $success]); + // Update the "last-update", "success_update" and "failure_update" field only when it is a public contact. + // These fields are set in OnePoll for all non public contacts. + $updated = DateTimeFormat::utcNow(); + if ($success) { + DBA::update('contact', ['last-update' => $updated, 'success_update' => $updated], ['id' => $contact_id, 'uid' => 0]); + } else { + DBA::update('contact', ['last-update' => $updated, 'failure_update' => $updated], ['id' => $contact_id, 'uid' => 0]); + } } }