From b1fdd118544f9eff7937589ba2624feccb824cda Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sat, 21 Aug 2021 15:51:29 -0400 Subject: [PATCH] [REF] - Clean up recentItems functions and add test Use array_filter() instead of brittle for() loops. --- CRM/Contact/BAO/Contact.php | 2 +- CRM/Utils/Recent.php | 76 +++++++------------ .../phpunit/api/v4/Action/RecentItemsTest.php | 62 +++++++++++++++ 3 files changed, 91 insertions(+), 49 deletions(-) create mode 100644 tests/phpunit/api/v4/Action/RecentItemsTest.php diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index 7e2ff0b74e..cb855c0b46 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -1063,7 +1063,7 @@ WHERE civicrm_contact.id = " . CRM_Utils_Type::escape($id, 'Integer'); } //delete the contact id from recently view - CRM_Utils_Recent::delContact($id); + CRM_Utils_Recent::del(['contact_id' => $id]); self::updateContactCache($id, empty($restore)); // delete any prevnext/dupe cache entry diff --git a/CRM/Utils/Recent.php b/CRM/Utils/Recent.php index 231f4af395..6463638519 100644 --- a/CRM/Utils/Recent.php +++ b/CRM/Utils/Recent.php @@ -90,22 +90,13 @@ class CRM_Utils_Recent { $contactName, $others = [] ) { - self::initialize(); - + // Abort if this entity type is not supported if (!self::isProviderEnabled($type)) { return; } - $session = CRM_Core_Session::singleton(); - - // make sure item is not already present in list - for ($i = 0; $i < count(self::$_recent); $i++) { - if (self::$_recent[$i]['type'] === $type && self::$_recent[$i]['id'] == $id) { - // delete item from array - array_splice(self::$_recent, $i, 1); - break; - } - } + // Ensure item is not already present in list + self::removeItems(['id' => $id, 'type' => $type]); if (!is_array($others)) { $others = []; @@ -127,12 +118,14 @@ class CRM_Utils_Recent { ] ); - if (count(self::$_recent) > self::$_maxItems) { + // Keep the list trimmed to max length + while (count(self::$_recent) > self::$_maxItems) { array_pop(self::$_recent); } CRM_Utils_Hook::recent(self::$_recent); + $session = CRM_Core_Session::singleton(); $session->set(self::STORE_NAME, self::$_recent); } @@ -151,27 +144,30 @@ class CRM_Utils_Recent { } /** - * Delete an item from the recent stack. - * - * @param array $recentItem - * Array of the recent Item to be removed. + * Remove items from the array that match given props + * @param array $props */ - public static function del($recentItem) { + private static function removeItems(array $props) { self::initialize(); - $tempRecent = self::$_recent; - - self::$_recent = []; - // make sure item is not already present in list - for ($i = 0; $i < count($tempRecent); $i++) { - if (!($tempRecent[$i]['id'] == $recentItem['id'] && - $tempRecent[$i]['type'] == $recentItem['type'] - ) - ) { - self::$_recent[] = $tempRecent[$i]; + self::$_recent = array_filter(self::$_recent, function($item) use ($props) { + foreach ($props as $key => $val) { + if (isset($item[$key]) && $item[$key] == $val) { + return FALSE; + } } - } + return TRUE; + }); + } + /** + * Delete item(s) from the recently-viewed list. + * + * @param array $removeItem + * Item to be removed. + */ + public static function del($removeItem) { + self::removeItems($removeItem); CRM_Utils_Hook::recent(self::$_recent); $session = CRM_Core_Session::singleton(); $session->set(self::STORE_NAME, self::$_recent); @@ -181,27 +177,11 @@ class CRM_Utils_Recent { * Delete an item from the recent stack. * * @param string $id - * Contact id that had to be removed. + * @deprecated */ public static function delContact($id) { - self::initialize(); - - $tempRecent = self::$_recent; - - self::$_recent = []; - - // rebuild recent. - for ($i = 0; $i < count($tempRecent); $i++) { - // don't include deleted contact in recent. - if (CRM_Utils_Array::value('contact_id', $tempRecent[$i]) == $id) { - continue; - } - self::$_recent[] = $tempRecent[$i]; - } - - CRM_Utils_Hook::recent(self::$_recent); - $session = CRM_Core_Session::singleton(); - $session->set(self::STORE_NAME, self::$_recent); + CRM_Core_Error::deprecatedFunctionWarning('del'); + self::del(['contact_id' => $id]); } /** diff --git a/tests/phpunit/api/v4/Action/RecentItemsTest.php b/tests/phpunit/api/v4/Action/RecentItemsTest.php new file mode 100644 index 0000000000..967e37a10e --- /dev/null +++ b/tests/phpunit/api/v4/Action/RecentItemsTest.php @@ -0,0 +1,62 @@ +createLoggedInUser(); + + $aid = Activity::create(FALSE) + ->addValue('activity_type_id:name', 'Meeting') + ->addValue('source_contact_id', $cid) + ->addValue('subject', 'Hello recent!') + ->execute()->first()['id']; + + $this->assertEquals(1, $this->getRecentItemCount(['type' => 'Activity', 'id' => $aid])); + + Activity::delete(FALSE)->addWhere('id', '=', $aid)->execute(); + + $this->assertEquals(0, $this->getRecentItemCount(['type' => 'Activity', 'id' => $aid])); + } + + private function getRecentItemCount($props) { + $count = 0; + foreach (\CRM_Utils_Recent::get() as $item) { + foreach ($props as $key => $val) { + if (($item[$key] ?? NULL) != $val) { + continue 2; + } + } + ++$count; + } + return $count; + } + +} -- 2.25.1