From 90b9ad8bedf3983d4f2e5a64e4dbe46d39d23ec9 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Wed, 28 Aug 2019 22:27:48 +0200 Subject: [PATCH 1/9] New contact table functions with check for duplicates --- src/Model/Contact.php | 60 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 6887b9d0a..a111589cc 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -136,6 +136,66 @@ class Contact extends BaseObject return $contact; } + /** + * @brief Insert a row into the contact table + * + * @param array $param parameter array + * @param bool $on_duplicate_update Do an update on a duplicate entry + * + * @return boolean was the insert successful? + * @throws \Exception + */ + public static function insert($param, $on_duplicate_update = false) + { + $ret = DBA::insert('contact', $param, $on_duplicate_update); + + $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], ['id' => DBA::lastInsertId()]); + if (!DBA::isResult($contact)) { + // Shouldn't happen + return $ret; + } + + // Search for duplicated contacts and get rid of them + self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']); + + return $ret; + } + + /** + * @param array $fields contains the fields that are updated + * @param array $condition condition array with the key values + * @param array|boolean $old_fields array with the old field values that are about to be replaced (true = update on duplicate) + * + * @return boolean was the update successfull? + * @throws \Exception + */ + public static function update($fields, $condition, $old_fields = []) + { + $ret = DBA::update('contact', $fields, $condition, $old_fields); + + // We quit when the update affected more than one row + if (DBA::affectedRows() > 1) { + return $ret; + } + + // Don't proceed when the command aboved queried more than one row + // This is not a duplicate of the test above since that only checked for affected rows + if (DBA::count('contact', $condition) != 1) { + return $ret; + } + + $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], $condition); + if (!DBA::isResult($contact)) { + // Shouldn't happen + return $ret; + } + + // Search for duplicated contacts and get rid of them + self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']); + + return $ret; + } + /** * @param integer $id Contact ID * @param array $fields Array of selected fields, empty for all From 141bcf149d41c6f9755d9645fd9063103ca3b05e Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 29 Aug 2019 06:06:41 +0200 Subject: [PATCH 2/9] Added post update to remove duplicated contacts --- src/Database/PostUpdate.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index acafea900..76ec3ea01 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -37,6 +37,9 @@ class PostUpdate if (!self::update1297()) { return false; } + if (!self::update1322()) { + return false; + } return true; } @@ -414,6 +417,38 @@ class PostUpdate Logger::info('Done'); + return true; + } + /** + * Set the delivery queue count to a negative value for all items preceding the feature. + * + * @return bool "true" when the job is done + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + private static function update1322() + { + // Was the script completed? + if (Config::get('system', 'post_update_version') >= 1322) { + return true; + } + + Logger::info('Start'); + + $contacts = DBA::p("SELECT ANY_VALUE(`id`) AS `id` FROM `contact` + WHERE EXISTS (SELECT `nurl` FROM `contact` AS `c2` + WHERE `c2`.`nurl` = `contact`.`nurl` AND `c2`.`id` != `contact`.`id` AND `c2`.`uid` = `contact`.`uid` AND `c2`.`network` = `contact`.`network`) + AND `network` IN (?, ?, ?) GROUP BY `nurl`", Protocol::DIASPORA, Protocol::OSTATUS, Protocol::ACTIVITYPUB); + + while ($contact = DBA::fetch($contacts)) { + Logger::info('Remove duplicates', ['id' => $contact['id']]); + Contact::handleDuplicateByID($contact['id']); + } + + DBA::close($contact); + Config::set('system', 'post_update_version', 1322); + + Logger::info('Done'); + return true; } } From ef02a1cb7b7d375d1ae0f607fecca8be9e72f0c8 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 29 Aug 2019 06:07:07 +0200 Subject: [PATCH 3/9] Check fpr duplicated contacts upon inserting them --- src/Model/Contact.php | 62 +++++++++++++++------------------------ src/Protocol/Diaspora.php | 2 +- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 5613dc396..49d4e4cc6 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -137,7 +137,8 @@ class Contact extends BaseObject } /** - * @brief Insert a row into the contact table + * Insert a row into the contact table + * Important: You can't use DBA::lastInsertId() after this call since it will be set to 0. * * @param array $param parameter array * @param bool $on_duplicate_update Do an update on a duplicate entry @@ -148,7 +149,6 @@ class Contact extends BaseObject public static function insert($param, $on_duplicate_update = false) { $ret = DBA::insert('contact', $param, $on_duplicate_update); - $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], ['id' => DBA::lastInsertId()]); if (!DBA::isResult($contact)) { // Shouldn't happen @@ -161,41 +161,6 @@ class Contact extends BaseObject return $ret; } - /** - * @param array $fields contains the fields that are updated - * @param array $condition condition array with the key values - * @param array|boolean $old_fields array with the old field values that are about to be replaced (true = update on duplicate) - * - * @return boolean was the update successfull? - * @throws \Exception - */ - public static function update($fields, $condition, $old_fields = []) - { - $ret = DBA::update('contact', $fields, $condition, $old_fields); - - // We quit when the update affected more than one row - if (DBA::affectedRows() > 1) { - return $ret; - } - - // Don't proceed when the command aboved queried more than one row - // This is not a duplicate of the test above since that only checked for affected rows - if (DBA::count('contact', $condition) != 1) { - return $ret; - } - - $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], $condition); - if (!DBA::isResult($contact)) { - // Shouldn't happen - return $ret; - } - - // Search for duplicated contacts and get rid of them - self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']); - - return $ret; - } - /** * @param integer $id Contact ID * @param array $fields Array of selected fields, empty for all @@ -1548,7 +1513,7 @@ class Contact extends BaseObject if (!DBA::isResult($contact)) { Logger::info('Create new contact', $fields); - DBA::insert('contact', $fields); + self::insert($fields); // We intentionally aren't using lastInsertId here. There is a chance for duplicates. $contact = DBA::selectFirst('contact', ['id'], $condition, ['order' => ['id']]); @@ -1954,6 +1919,25 @@ class Contact extends BaseObject DBA::update('contact', $fields, $condition); } + /** + * Check and remove duplicate contact entries + * + * @param integer $contact_id Contact ID + * @throws \Exception + */ + public static function handleDuplicateByID($contact_id) + { + $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], ['id' => $contact_id]); + if (!DBA::isResult($contact)) { + return $ret; + } + + // Search for duplicated contacts and get rid of them + self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']); + + return $ret; + } + /** * @brief Helper function for "updateFromProbe". Remove duplicated contacts * @@ -2325,7 +2309,7 @@ class Contact extends BaseObject $new_relation = (in_array($protocol, [Protocol::MAIL]) ? self::FRIEND : self::SHARING); // create contact record - DBA::insert('contact', [ + self::insert([ 'uid' => $uid, 'created' => DateTimeFormat::utcNow(), 'url' => $ret['url'], diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index d578ba454..b694ab917 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -200,7 +200,7 @@ class Diaspora DBA::update('contact', $fields, $condition, $old); } else { Logger::info('Create relay contact', ['fields' => $fields]); - DBA::insert('contact', $fields); + Contact::insert($fields); } } From 503a5be06c109c71fa5bf5a1c3e18695e4529771 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 29 Aug 2019 06:55:36 +0200 Subject: [PATCH 4/9] Fixed query (not all duplicates had been found) --- src/Database/PostUpdate.php | 8 +++++--- src/Model/Contact.php | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index 76ec3ea01..651766fcf 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -434,10 +434,12 @@ class PostUpdate Logger::info('Start'); - $contacts = DBA::p("SELECT ANY_VALUE(`id`) AS `id` FROM `contact` + $contacts = DBA::p("SELECT ANY_VALUE(`id`) AS `id`, ANY_VALUE(`nurl`) AS `nurl` FROM `contact` WHERE EXISTS (SELECT `nurl` FROM `contact` AS `c2` - WHERE `c2`.`nurl` = `contact`.`nurl` AND `c2`.`id` != `contact`.`id` AND `c2`.`uid` = `contact`.`uid` AND `c2`.`network` = `contact`.`network`) - AND `network` IN (?, ?, ?) GROUP BY `nurl`", Protocol::DIASPORA, Protocol::OSTATUS, Protocol::ACTIVITYPUB); + WHERE `c2`.`nurl` = `contact`.`nurl` AND `c2`.`id` != `contact`.`id` AND `c2`.`uid` = `contact`.`uid` AND `c2`.`network` IN (?, ?, ?)) + AND (`network` IN (?, ?, ?) OR (`uid` = ?)) GROUP BY `nurl`, `uid`", + Protocol::DIASPORA, Protocol::OSTATUS, Protocol::ACTIVITYPUB, + Protocol::DIASPORA, Protocol::OSTATUS, Protocol::ACTIVITYPUB, 0); while ($contact = DBA::fetch($contacts)) { Logger::info('Remove duplicates', ['id' => $contact['id']]); diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 49d4e4cc6..ca3ac4411 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1929,13 +1929,13 @@ class Contact extends BaseObject { $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], ['id' => $contact_id]); if (!DBA::isResult($contact)) { - return $ret; + return; } // Search for duplicated contacts and get rid of them self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']); - return $ret; + return; } /** From 66eab2b44fd5562e50375374ac3f8a8e28d8dada Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 29 Aug 2019 07:22:29 +0200 Subject: [PATCH 5/9] Don't handle deleted contacts / removed unneeded parameter --- src/Database/PostUpdate.php | 4 ++-- src/Model/Contact.php | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index 651766fcf..2e3af8597 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -436,8 +436,8 @@ class PostUpdate $contacts = DBA::p("SELECT ANY_VALUE(`id`) AS `id`, ANY_VALUE(`nurl`) AS `nurl` FROM `contact` WHERE EXISTS (SELECT `nurl` FROM `contact` AS `c2` - WHERE `c2`.`nurl` = `contact`.`nurl` AND `c2`.`id` != `contact`.`id` AND `c2`.`uid` = `contact`.`uid` AND `c2`.`network` IN (?, ?, ?)) - AND (`network` IN (?, ?, ?) OR (`uid` = ?)) GROUP BY `nurl`, `uid`", + WHERE `c2`.`nurl` = `contact`.`nurl` AND `c2`.`id` != `contact`.`id` AND `c2`.`uid` = `contact`.`uid` AND `c2`.`network` IN (?, ?, ?) AND NOT `deleted`) + AND (`network` IN (?, ?, ?) OR (`uid` = ?)) AND NOT `deleted` GROUP BY `nurl`, `uid`", Protocol::DIASPORA, Protocol::OSTATUS, Protocol::ACTIVITYPUB, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::ACTIVITYPUB, 0); diff --git a/src/Model/Contact.php b/src/Model/Contact.php index ca3ac4411..b0e8ec613 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -149,14 +149,14 @@ class Contact extends BaseObject public static function insert($param, $on_duplicate_update = false) { $ret = DBA::insert('contact', $param, $on_duplicate_update); - $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], ['id' => DBA::lastInsertId()]); + $contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => DBA::lastInsertId()]); if (!DBA::isResult($contact)) { // Shouldn't happen return $ret; } // Search for duplicated contacts and get rid of them - self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']); + self::handleDuplicates($contact['nurl'], $contact['uid']); return $ret; } @@ -1878,7 +1878,7 @@ class Contact extends BaseObject } // Search for duplicated contacts and get rid of them - if (self::handleDuplicates(Strings::normaliseLink($url), $uid, $id) || ($uid != 0)) { + if (self::handleDuplicates(Strings::normaliseLink($url), $uid) || ($uid != 0)) { return; } @@ -1927,13 +1927,13 @@ class Contact extends BaseObject */ public static function handleDuplicateByID($contact_id) { - $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], ['id' => $contact_id]); + $contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => $contact_id, 'deleted' => false]); if (!DBA::isResult($contact)) { return; } // Search for duplicated contacts and get rid of them - self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']); + self::handleDuplicates($contact['nurl'], $contact['uid']); return; } @@ -1943,11 +1943,10 @@ class Contact extends BaseObject * * @param string $nurl Normalised contact url * @param integer $uid User id - * @param integer $id Contact id of a duplicate * @return boolean * @throws \Exception */ - private static function handleDuplicates($nurl, $uid, $id) + private static function handleDuplicates($nurl, $uid) { $condition = ['nurl' => $nurl, 'uid' => $uid, 'deleted' => false, 'network' => Protocol::FEDERATED]; $count = DBA::count('contact', $condition); @@ -1962,7 +1961,7 @@ class Contact extends BaseObject } $first = $first_contact['id']; - Logger::info('Found duplicates', ['count' => $count, 'id' => $id, 'first' => $first, 'uid' => $uid, 'nurl' => $nurl]); + Logger::info('Found duplicates', ['count' => $count, 'first' => $first, 'uid' => $uid, 'nurl' => $nurl]); if (($uid != 0 && ($first_contact['network'] == Protocol::DFRN))) { // Don't handle non public DFRN duplicates by now (legacy DFRN is very special because of the key handling) Logger::info('Not handling non public DFRN duplicate', ['uid' => $uid, 'nurl' => $nurl]); From 481376dd6f9ccbc54e4e302f8e08ba3f84646882 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 29 Aug 2019 08:41:55 +0200 Subject: [PATCH 6/9] Avoid not performing unarchiving --- src/Model/Contact.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index b0e8ec613..dfabf260d 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -903,6 +903,13 @@ class Contact extends BaseObject */ public static function unmarkForArchival(array $contact) { + // Always unarchive the relay contact entry + if (!empty($contact['batch'])) { + $fields = ['term-date' => DBA::NULL_DATETIME, 'archive' => false]; + $condition = ['batch' => $contact['batch'], 'contact-type' => self::TYPE_RELAY]; + DBA::update('contact', $fields, $condition); + } + $condition = ['`id` = ? AND (`term-date` > ? OR `archive`)', $contact['id'], DBA::NULL_DATETIME]; $exists = DBA::exists('contact', $condition); @@ -926,11 +933,6 @@ class Contact extends BaseObject DBA::update('contact', $fields, ['id' => $contact['id']]); DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]); GContact::updateFromPublicContactURL($contact['url']); - - if (!empty($contact['batch'])) { - $condition = ['batch' => $contact['batch'], 'contact-type' => self::TYPE_RELAY]; - DBA::update('contact', $fields, $condition); - } } /** From 438394bc1d4478974b26fe5b1ce1dfa1acbf820f Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Fri, 30 Aug 2019 07:38:42 +0200 Subject: [PATCH 7/9] Type hints, corrected wrong documentation --- src/Database/PostUpdate.php | 2 +- src/Model/Contact.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index 2e3af8597..8c5414bfc 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -420,7 +420,7 @@ class PostUpdate return true; } /** - * Set the delivery queue count to a negative value for all items preceding the feature. + * Remove contact duplicates * * @return bool "true" when the job is done * @throws \Friendica\Network\HTTPException\InternalServerErrorException diff --git a/src/Model/Contact.php b/src/Model/Contact.php index dfabf260d..a8dc673bc 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -146,7 +146,7 @@ class Contact extends BaseObject * @return boolean was the insert successful? * @throws \Exception */ - public static function insert($param, $on_duplicate_update = false) + public static function insert(array $param, bool $on_duplicate_update = false) { $ret = DBA::insert('contact', $param, $on_duplicate_update); $contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => DBA::lastInsertId()]); @@ -1927,7 +1927,7 @@ class Contact extends BaseObject * @param integer $contact_id Contact ID * @throws \Exception */ - public static function handleDuplicateByID($contact_id) + public static function handleDuplicateByID(int $contact_id) { $contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => $contact_id, 'deleted' => false]); if (!DBA::isResult($contact)) { @@ -1948,7 +1948,7 @@ class Contact extends BaseObject * @return boolean * @throws \Exception */ - private static function handleDuplicates($nurl, $uid) + private static function handleDuplicates(string $nurl, int $uid) { $condition = ['nurl' => $nurl, 'uid' => $uid, 'deleted' => false, 'network' => Protocol::FEDERATED]; $count = DBA::count('contact', $condition); From 3b92f7357c617899a2b0ee9dc341f039cc941ed8 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Fri, 30 Aug 2019 07:52:21 +0200 Subject: [PATCH 8/9] Renamed function --- src/Database/PostUpdate.php | 6 +++--- src/Model/Contact.php | 27 ++++----------------------- 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/src/Database/PostUpdate.php b/src/Database/PostUpdate.php index 8c5414bfc..885c9eea0 100644 --- a/src/Database/PostUpdate.php +++ b/src/Database/PostUpdate.php @@ -434,7 +434,7 @@ class PostUpdate Logger::info('Start'); - $contacts = DBA::p("SELECT ANY_VALUE(`id`) AS `id`, ANY_VALUE(`nurl`) AS `nurl` FROM `contact` + $contacts = DBA::p("SELECT `nurl`, `uid` FROM `contact` WHERE EXISTS (SELECT `nurl` FROM `contact` AS `c2` WHERE `c2`.`nurl` = `contact`.`nurl` AND `c2`.`id` != `contact`.`id` AND `c2`.`uid` = `contact`.`uid` AND `c2`.`network` IN (?, ?, ?) AND NOT `deleted`) AND (`network` IN (?, ?, ?) OR (`uid` = ?)) AND NOT `deleted` GROUP BY `nurl`, `uid`", @@ -442,8 +442,8 @@ class PostUpdate Protocol::DIASPORA, Protocol::OSTATUS, Protocol::ACTIVITYPUB, 0); while ($contact = DBA::fetch($contacts)) { - Logger::info('Remove duplicates', ['id' => $contact['id']]); - Contact::handleDuplicateByID($contact['id']); + Logger::info('Remove duplicates', ['nurl' => $contact['nurl'], 'uid' => $contact['uid']]); + Contact::removeDuplicates($contact['nurl'], $contact['uid']); } DBA::close($contact); diff --git a/src/Model/Contact.php b/src/Model/Contact.php index a8dc673bc..eb99a9fe0 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -156,7 +156,7 @@ class Contact extends BaseObject } // Search for duplicated contacts and get rid of them - self::handleDuplicates($contact['nurl'], $contact['uid']); + self::removeDuplicates($contact['nurl'], $contact['uid']); return $ret; } @@ -1880,7 +1880,7 @@ class Contact extends BaseObject } // Search for duplicated contacts and get rid of them - if (self::handleDuplicates(Strings::normaliseLink($url), $uid) || ($uid != 0)) { + if (self::removeDuplicates(Strings::normaliseLink($url), $uid) || ($uid != 0)) { return; } @@ -1921,34 +1921,15 @@ class Contact extends BaseObject DBA::update('contact', $fields, $condition); } - /** - * Check and remove duplicate contact entries - * - * @param integer $contact_id Contact ID - * @throws \Exception - */ - public static function handleDuplicateByID(int $contact_id) - { - $contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => $contact_id, 'deleted' => false]); - if (!DBA::isResult($contact)) { - return; - } - - // Search for duplicated contacts and get rid of them - self::handleDuplicates($contact['nurl'], $contact['uid']); - - return; - } - /** - * @brief Helper function for "updateFromProbe". Remove duplicated contacts + * @brief Remove duplicated contacts * * @param string $nurl Normalised contact url * @param integer $uid User id * @return boolean * @throws \Exception */ - private static function handleDuplicates(string $nurl, int $uid) + public static function removeDuplicates(string $nurl, int $uid) { $condition = ['nurl' => $nurl, 'uid' => $uid, 'deleted' => false, 'network' => Protocol::FEDERATED]; $count = DBA::count('contact', $condition); From f293e352ecd70b9745ec366d1ab49641503c40d8 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Fri, 30 Aug 2019 07:59:18 +0200 Subject: [PATCH 9/9] Renamed function parameter --- src/Model/Contact.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index eb99a9fe0..b18ebc22d 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -140,15 +140,15 @@ class Contact extends BaseObject * Insert a row into the contact table * Important: You can't use DBA::lastInsertId() after this call since it will be set to 0. * - * @param array $param parameter array + * @param array $fields field array * @param bool $on_duplicate_update Do an update on a duplicate entry * * @return boolean was the insert successful? * @throws \Exception */ - public static function insert(array $param, bool $on_duplicate_update = false) + public static function insert(array $fields, bool $on_duplicate_update = false) { - $ret = DBA::insert('contact', $param, $on_duplicate_update); + $ret = DBA::insert('contact', $fields, $on_duplicate_update); $contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => DBA::lastInsertId()]); if (!DBA::isResult($contact)) { // Shouldn't happen