X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FUtils%2FRecent.php;h=f09ce294bbbb795e667bb1f15f1d5d8731948ea1;hb=f8307138bf292130a628e68f346535b398ae9b63;hp=fc98cc37fe9488e238f2260aecd84783aa7e2cbf;hpb=269e0a555069731fb0995b1b0d5a82d45b07c1df;p=civicrm-core.git diff --git a/CRM/Utils/Recent.php b/CRM/Utils/Recent.php index fc98cc37fe..f09ce294bb 100644 --- a/CRM/Utils/Recent.php +++ b/CRM/Utils/Recent.php @@ -14,6 +14,8 @@ * @copyright CiviCRM LLC https://civicrm.org/licensing */ +use Civi\Api4\Utils\CoreUtil; + /** * Recent items utility class. */ @@ -74,6 +76,30 @@ class CRM_Utils_Recent { return self::$_recent; } + /** + * Create function used by the API - supplies defaults + * + * @param array $params + * @param Civi\Api4\Generic\AbstractAction $action + */ + public static function create(array $params, Civi\Api4\Generic\AbstractAction $action) { + if ($action->getCheckPermissions()) { + $allowed = civicrm_api4($params['entity_type'], 'checkAccess', [ + 'action' => 'get', + 'values' => ['id' => $params['entity_id']], + ], 0); + if (empty($allowed['access'])) { + return []; + } + } + $params['title'] = $params['title'] ?? self::getTitle($params['entity_type'], $params['entity_id']); + $params['view_url'] = $params['view_url'] ?? self::getUrl($params['entity_type'], $params['entity_id'], 'view'); + $params['edit_url'] = $params['edit_url'] ?? self::getUrl($params['entity_type'], $params['entity_id'], 'update'); + $params['delete_url'] = $params['delete_url'] ?? (empty($params['is_deleted']) ? self::getUrl($params['entity_type'], $params['entity_id'], 'delete') : NULL); + self::add($params['title'], $params['view_url'], $params['entity_id'], $params['entity_type'], $params['contact_id'] ?? NULL, NULL, $params); + return $params; + } + /** * Add an item to the recent stack. * @@ -81,29 +107,33 @@ class CRM_Utils_Recent { * The title to display. * @param string $url * The link for the above title. - * @param string $id + * @param string $entityId * Object id. - * @param string $type + * @param string $entityType * @param int $contactId + * Deprecated, probably unused param * @param string $contactName + * Deprecated, probably unused param * @param array $others */ public static function add( $title, $url, - $id, - $type, + $entityId, + $entityType, $contactId, $contactName, $others = [] ) { + $entityType = self::normalizeEntityType($entityType); + // Abort if this entity type is not supported - if (!self::isProviderEnabled($type)) { + if (!self::isProviderEnabled($entityType)) { return; } // Ensure item is not already present in list - self::removeItems(['id' => $id, 'type' => $type]); + self::removeItems(['entity_id' => $entityId, 'entity_type' => $entityType]); if (!is_array($others)) { $others = []; @@ -112,17 +142,28 @@ class CRM_Utils_Recent { array_unshift(self::$_recent, [ 'title' => $title, + // TODO: deprecate & remove "url" in favor of "view_url" 'url' => $url, - 'id' => $id, - 'type' => $type, + 'view_url' => $url, + // TODO: deprecate & remove "id" in favor of "entity_id" + 'id' => $entityId, + 'entity_id' => (int) $entityId, + // TODO: deprecate & remove "type" in favor of "entity_type" + 'type' => $entityType, + 'entity_type' => $entityType, + // Deprecated param 'contact_id' => $contactId, + // Param appears to be unused 'contactName' => $contactName, 'subtype' => $others['subtype'] ?? NULL, - 'isDeleted' => $others['isDeleted'] ?? FALSE, + // TODO: deprecate & remove "isDeleted" in favor of "is_deleted" + 'isDeleted' => $others['is_deleted'] ?? $others['isDeleted'] ?? FALSE, + 'is_deleted' => (bool) ($others['is_deleted'] ?? $others['isDeleted'] ?? FALSE), + // imageUrl is deprecated 'image_url' => $others['imageUrl'] ?? NULL, - 'edit_url' => $others['editUrl'] ?? NULL, - 'delete_url' => $others['deleteUrl'] ?? NULL, - 'icon' => $others['icon'] ?? self::getIcon($type, $others['subtype'] ?? NULL), + 'edit_url' => $others['edit_url'] ?? $others['editUrl'] ?? NULL, + 'delete_url' => $others['delete_url'] ?? $others['deleteUrl'] ?? NULL, + 'icon' => $others['icon'] ?? self::getIcon($entityType, $entityId), ] ); @@ -138,28 +179,63 @@ class CRM_Utils_Recent { } /** - * @param $type - * @param $subType + * Get default title for this item, based on the entity's `label_field` + * + * @param string $entityType + * @param int $entityId * @return string|null */ - private static function getIcon($type, $subType) { - $icon = NULL; - $contactTypes = CRM_Contact_BAO_ContactType::getAllContactTypes(); - if (!empty($contactTypes[$type])) { - // Pick icon from contact sub-type first if available, then contact type - $subTypesAndType = array_merge((array) CRM_Utils_Array::explodePadded($subType), [$type]); - foreach ($subTypesAndType as $contactType) { - $icon = $icon ?? $contactTypes[$contactType]['icon'] ?? NULL; - } - // If no contact type icon, proceed to lookup icon from dao - $type = 'Contact'; + private static function getTitle($entityType, $entityId) { + $labelField = CoreUtil::getInfoItem($entityType, 'label_field'); + $title = NULL; + if ($labelField) { + $record = civicrm_api4($entityType, 'get', [ + 'where' => [['id', '=', $entityId]], + 'select' => [$labelField], + 'checkPermissions' => FALSE, + ], 0); + $title = $record[$labelField] ?? NULL; } - if (!$icon) { - $daoClass = CRM_Core_DAO_AllCoreTables::getFullName($type); - if ($daoClass) { - $icon = $daoClass::$_icon; + return $title ?? (CoreUtil::getInfoItem($entityType, 'title')); + } + + /** + * Get a link to view/update/delete a given entity. + * + * @param string $entityType + * @param int $entityId + * @param string $action + * Either 'view', 'update', or 'delete' + * @return string|null + */ + private static function getUrl($entityType, $entityId, $action) { + if ($action !== 'view') { + $check = civicrm_api4($entityType, 'checkAccess', [ + 'action' => $action, + 'values' => ['id' => $entityId], + ], 0); + if (empty($check['access'])) { + return NULL; } } + $paths = (array) CoreUtil::getInfoItem($entityType, 'paths'); + if (!empty($paths[$action])) { + return CRM_Utils_System::url(str_replace('[id]', $entityId, $paths[$action])); + } + return NULL; + } + + /** + * @param $entityType + * @param $entityId + * @return string|null + */ + private static function getIcon($entityType, $entityId) { + $icon = NULL; + $daoClass = CRM_Core_DAO_AllCoreTables::getFullName($entityType); + if ($daoClass) { + $icon = CRM_Core_DAO_AllCoreTables::getBAOClassName($daoClass)::getEntityIcon($entityType, $entityId); + } return $icon ?: 'fa-gear'; } @@ -168,11 +244,23 @@ class CRM_Utils_Recent { * @param \Civi\Core\Event\PostEvent $event */ public static function on_hook_civicrm_post(\Civi\Core\Event\PostEvent $event) { - if ($event->action === 'delete' && $event->id && CRM_Core_Session::getLoggedInContactID()) { - // Is this an entity that might be in the recent items list? - $providersPermitted = Civi::settings()->get('recentItemsProviders') ?: array_keys(self::getProviders()); - if (in_array($event->entity, $providersPermitted)) { - self::del(['id' => $event->id, 'type' => $event->entity]); + if ($event->id && CRM_Core_Session::getLoggedInContactID()) { + $entityType = self::normalizeEntityType($event->entity); + if ($event->action === 'delete') { + // Is this an entity that might be in the recent items list? + $providersPermitted = Civi::settings()->get('recentItemsProviders') ?: array_keys(self::getProviders()); + if (in_array($entityType, $providersPermitted)) { + self::del(['entity_id' => $event->id, 'entity_type' => $entityType]); + } + } + elseif ($event->action === 'edit') { + if (isset($event->object->is_deleted)) { + \Civi\Api4\RecentItem::update(FALSE) + ->addWhere('entity_type', '=', $entityType) + ->addWhere('entity_id', '=', $event->id) + ->addValue('is_deleted', (bool) $event->object->is_deleted) + ->execute(); + } } } } @@ -186,7 +274,7 @@ class CRM_Utils_Recent { self::$_recent = array_filter(self::$_recent, function($item) use ($props) { foreach ($props as $key => $val) { - if (isset($item[$key]) && $item[$key] != $val) { + if (($item[$key] ?? NULL) != $val) { return TRUE; } } @@ -226,12 +314,6 @@ class CRM_Utils_Recent { * @return bool */ public static function isProviderEnabled($providerName) { - - // Join contact types to providerName 'Contact' - $contactTypes = CRM_Contact_BAO_ContactType::contactTypes(TRUE); - if (in_array($providerName, $contactTypes)) { - $providerName = 'Contact'; - } $allowed = TRUE; // Use core setting recentItemsProviders if configured @@ -243,9 +325,23 @@ class CRM_Utils_Recent { return $allowed; } + /** + * @param string $entityType + * @return string + */ + private static function normalizeEntityType($entityType) { + // Change Individual/Organization/Household to 'Contact' + if (in_array($entityType, CRM_Contact_BAO_ContactType::basicTypes(TRUE), TRUE)) { + return 'Contact'; + } + return $entityType; + } + /** * Gets the list of available providers to civi's recent items stack * + * TODO: Make this an option group so extensions can extend it. + * * @return array */ public static function getProviders() {