Commit | Line | Data |
---|---|---|
6a488035 | 1 | <?php |
6a488035 TO |
2 | /* |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 5 | | | |
bc77d7c0 TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
6a488035 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
6a488035 | 13 | * @package CRM |
ca5cec67 | 14 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 TO |
15 | */ |
16 | ||
17 | /** | |
b8c71ffa | 18 | * Recent items utility class. |
6a488035 TO |
19 | */ |
20 | class CRM_Utils_Recent { | |
21 | ||
22 | /** | |
ac5f7c7f | 23 | * Store name |
6a488035 | 24 | * |
ac5f7c7f | 25 | * @var string |
6a488035 | 26 | */ |
074585b6 | 27 | const MAX_ITEMS = 30, STORE_NAME = 'CRM_Utils_Recent'; |
6a488035 TO |
28 | |
29 | /** | |
fe482240 | 30 | * The list of recently viewed items. |
6a488035 TO |
31 | * |
32 | * @var array | |
6a488035 TO |
33 | */ |
34 | static private $_recent = NULL; | |
35 | ||
ac5f7c7f NH |
36 | /** |
37 | * Maximum stack size | |
38 | * @var int | |
39 | */ | |
074585b6 | 40 | static private $_maxItems = 10; |
7943980b | 41 | |
6a488035 | 42 | /** |
fe482240 | 43 | * Initialize this class and set the static variables. |
6a488035 | 44 | */ |
00be9182 | 45 | public static function initialize() { |
43959a8a | 46 | $maxItemsSetting = Civi::settings()->get('recentItemsMaxCount'); |
074585b6 | 47 | if (isset($maxItemsSetting) && $maxItemsSetting > 0 && $maxItemsSetting < self::MAX_ITEMS) { |
136b401b NH |
48 | self::$_maxItems = $maxItemsSetting; |
49 | } | |
6a488035 TO |
50 | if (!self::$_recent) { |
51 | $session = CRM_Core_Session::singleton(); | |
52 | self::$_recent = $session->get(self::STORE_NAME); | |
53 | if (!self::$_recent) { | |
be2fb01f | 54 | self::$_recent = []; |
6a488035 TO |
55 | } |
56 | } | |
57 | } | |
58 | ||
59 | /** | |
fe482240 | 60 | * Return the recently viewed array. |
6a488035 | 61 | * |
a6c01b45 CW |
62 | * @return array |
63 | * the recently viewed array | |
6a488035 | 64 | */ |
00be9182 | 65 | public static function &get() { |
6a488035 TO |
66 | self::initialize(); |
67 | return self::$_recent; | |
68 | } | |
69 | ||
70 | /** | |
fe482240 | 71 | * Add an item to the recent stack. |
6a488035 | 72 | * |
77855840 TO |
73 | * @param string $title |
74 | * The title to display. | |
75 | * @param string $url | |
76 | * The link for the above title. | |
77 | * @param string $id | |
78 | * Object id. | |
f4aaa82a | 79 | * @param $type |
100fef9d CW |
80 | * @param int $contactId |
81 | * @param string $contactName | |
f4aaa82a | 82 | * @param array $others |
6a488035 | 83 | */ |
608e6658 | 84 | public static function add( |
a3e55d9c | 85 | $title, |
6a488035 TO |
86 | $url, |
87 | $id, | |
88 | $type, | |
89 | $contactId, | |
90 | $contactName, | |
be2fb01f | 91 | $others = [] |
6a488035 | 92 | ) { |
b1fdd118 | 93 | // Abort if this entity type is not supported |
136b401b NH |
94 | if (!self::isProviderEnabled($type)) { |
95 | return; | |
96 | } | |
97 | ||
b1fdd118 CW |
98 | // Ensure item is not already present in list |
99 | self::removeItems(['id' => $id, 'type' => $type]); | |
6a488035 TO |
100 | |
101 | if (!is_array($others)) { | |
be2fb01f | 102 | $others = []; |
6a488035 TO |
103 | } |
104 | ||
105 | array_unshift(self::$_recent, | |
be2fb01f | 106 | [ |
6a488035 TO |
107 | 'title' => $title, |
108 | 'url' => $url, | |
109 | 'id' => $id, | |
110 | 'type' => $type, | |
111 | 'contact_id' => $contactId, | |
112 | 'contactName' => $contactName, | |
6b409353 | 113 | 'subtype' => $others['subtype'] ?? NULL, |
6187cca4 | 114 | 'isDeleted' => $others['isDeleted'] ?? FALSE, |
6b409353 CW |
115 | 'image_url' => $others['imageUrl'] ?? NULL, |
116 | 'edit_url' => $others['editUrl'] ?? NULL, | |
117 | 'delete_url' => $others['deleteUrl'] ?? NULL, | |
be2fb01f | 118 | ] |
6a488035 | 119 | ); |
136b401b | 120 | |
b1fdd118 CW |
121 | // Keep the list trimmed to max length |
122 | while (count(self::$_recent) > self::$_maxItems) { | |
6a488035 TO |
123 | array_pop(self::$_recent); |
124 | } | |
125 | ||
126 | CRM_Utils_Hook::recent(self::$_recent); | |
127 | ||
b1fdd118 | 128 | $session = CRM_Core_Session::singleton(); |
6a488035 TO |
129 | $session->set(self::STORE_NAME, self::$_recent); |
130 | } | |
131 | ||
54043949 CW |
132 | /** |
133 | * Callback for hook_civicrm_post(). | |
134 | * @param \Civi\Core\Event\PostEvent $event | |
135 | */ | |
136 | public static function on_hook_civicrm_post(\Civi\Core\Event\PostEvent $event) { | |
137 | if ($event->action === 'delete' && $event->id && CRM_Core_Session::getLoggedInContactID()) { | |
138 | // Is this an entity that might be in the recent items list? | |
139 | $providersPermitted = Civi::settings()->get('recentItemsProviders') ?: array_keys(self::getProviders()); | |
140 | if (in_array($event->entity, $providersPermitted)) { | |
141 | self::del(['id' => $event->id, 'type' => $event->entity]); | |
142 | } | |
143 | } | |
144 | } | |
145 | ||
6a488035 | 146 | /** |
b1fdd118 CW |
147 | * Remove items from the array that match given props |
148 | * @param array $props | |
6a488035 | 149 | */ |
b1fdd118 | 150 | private static function removeItems(array $props) { |
6a488035 | 151 | self::initialize(); |
6a488035 | 152 | |
b1fdd118 CW |
153 | self::$_recent = array_filter(self::$_recent, function($item) use ($props) { |
154 | foreach ($props as $key => $val) { | |
a51ed717 CW |
155 | if (isset($item[$key]) && $item[$key] != $val) { |
156 | return TRUE; | |
b1fdd118 | 157 | } |
6a488035 | 158 | } |
a51ed717 | 159 | return FALSE; |
b1fdd118 CW |
160 | }); |
161 | } | |
6a488035 | 162 | |
b1fdd118 CW |
163 | /** |
164 | * Delete item(s) from the recently-viewed list. | |
165 | * | |
166 | * @param array $removeItem | |
167 | * Item to be removed. | |
168 | */ | |
169 | public static function del($removeItem) { | |
170 | self::removeItems($removeItem); | |
ab217754 | 171 | CRM_Utils_Hook::recent(self::$_recent); |
6a488035 TO |
172 | $session = CRM_Core_Session::singleton(); |
173 | $session->set(self::STORE_NAME, self::$_recent); | |
174 | } | |
175 | ||
176 | /** | |
fe482240 | 177 | * Delete an item from the recent stack. |
6a488035 | 178 | * |
77855840 | 179 | * @param string $id |
b1fdd118 | 180 | * @deprecated |
6a488035 | 181 | */ |
00be9182 | 182 | public static function delContact($id) { |
b1fdd118 CW |
183 | CRM_Core_Error::deprecatedFunctionWarning('del'); |
184 | self::del(['contact_id' => $id]); | |
6a488035 | 185 | } |
96025800 | 186 | |
ac5f7c7f NH |
187 | /** |
188 | * Check if a provider is allowed to add stuff. | |
ab217754 | 189 | * If corresponding setting is empty, all are allowed |
136b401b | 190 | * |
ac5f7c7f | 191 | * @param string $providerName |
ab217754 | 192 | * @return bool |
ac5f7c7f NH |
193 | */ |
194 | public static function isProviderEnabled($providerName) { | |
136b401b NH |
195 | |
196 | // Join contact types to providerName 'Contact' | |
197 | $contactTypes = CRM_Contact_BAO_ContactType::contactTypes(TRUE); | |
198 | if (in_array($providerName, $contactTypes)) { | |
199 | $providerName = 'Contact'; | |
200 | } | |
201 | $allowed = TRUE; | |
202 | ||
203 | // Use core setting recentItemsProviders if configured | |
43959a8a | 204 | $providersPermitted = Civi::settings()->get('recentItemsProviders'); |
136b401b NH |
205 | if ($providersPermitted) { |
206 | $allowed = in_array($providerName, $providersPermitted); | |
207 | } | |
208 | // Else allow | |
209 | return $allowed; | |
ac5f7c7f NH |
210 | } |
211 | ||
212 | /** | |
213 | * Gets the list of available providers to civi's recent items stack | |
ab217754 CW |
214 | * |
215 | * @return array | |
ac5f7c7f NH |
216 | */ |
217 | public static function getProviders() { | |
be2fb01f | 218 | $providers = [ |
136b401b NH |
219 | 'Contact' => ts('Contacts'), |
220 | 'Relationship' => ts('Relationships'), | |
221 | 'Activity' => ts('Activities'), | |
222 | 'Note' => ts('Notes'), | |
223 | 'Group' => ts('Groups'), | |
224 | 'Case' => ts('Cases'), | |
225 | 'Contribution' => ts('Contributions'), | |
226 | 'Participant' => ts('Participants'), | |
227 | 'Grant' => ts('Grants'), | |
228 | 'Membership' => ts('Memberships'), | |
229 | 'Pledge' => ts('Pledges'), | |
230 | 'Event' => ts('Events'), | |
231 | 'Campaign' => ts('Campaigns'), | |
be2fb01f | 232 | ]; |
ac5f7c7f | 233 | |
136b401b | 234 | return $providers; |
ac5f7c7f | 235 | } |
7943980b | 236 | |
6a488035 | 237 | } |