*/
class CRM_Admin_Form_ContactType extends CRM_Admin_Form {
+ public function preProcess(): void {
+ CRM_Utils_Request::retrieve('action', 'String', $this);
+ CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE, 0);
+ $this->set('BAOName', 'CRM_Contact_BAO_ContactType');
+ parent::preProcess();
+ }
+
/**
* Build the form object.
*/
self::$_links = [
CRM_Core_Action::UPDATE => [
'name' => ts('Edit'),
- 'url' => 'civicrm/admin/options/subtype',
+ 'url' => 'civicrm/admin/options/subtype/edit',
'qs' => 'action=update&id=%%id%%&reset=1',
'title' => ts('Edit Contact Type'),
],
],
CRM_Core_Action::DELETE => [
'name' => ts('Delete'),
- 'url' => 'civicrm/admin/options/subtype',
+ 'url' => 'civicrm/admin/options/subtype/edit',
'qs' => 'action=delete&id=%%id%%',
'title' => ts('Delete Contact Type'),
],
public function run() {
$action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 0);
$this->assign('action', $action);
- $id = CRM_Utils_Request::retrieve('id', 'Positive', $this, FALSE, 0);
if (!$action) {
$this->browse();
}
return $contactTypes;
}
+ /**
+ * @param string $entityName
+ * @param string $action
+ * @param array $record
+ * @param $userID
+ * @return bool
+ * @see CRM_Core_DAO::checkAccess
+ */
+ public static function _checkAccess(string $entityName, string $action, array $record, $userID): bool {
+ // Only records with a parent may be deleted
+ if ($action === 'delete') {
+ if (!array_key_exists('parent_id', $record)) {
+ $record['parent_id'] = CRM_Core_DAO::getFieldValue(parent::class, $record['id'], 'parent_id');
+ }
+ return (bool) $record['parent_id'];
+ }
+ // Gatekeeper permissions suffice for everything else
+ return TRUE;
+ }
+
}
*
* Generated from xml/schema/CRM/Contact/ContactType.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:13c81c203681009e8f71fd8387ebdbc2)
+ * (GenCodeChecksum:9858d69cd4bfdc5a3ce45c77eecd1145)
*/
/**
*/
public static $_log = FALSE;
+ /**
+ * Paths for accessing this entity in the UI.
+ *
+ * @var string[]
+ */
+ protected static $_paths = [
+ 'add' => 'civicrm/admin/options/subtype/edit?action=add&reset=1',
+ 'update' => 'civicrm/admin/options/subtype/edit?action=update&id=[id]&reset=1',
+ 'delete' => 'civicrm/admin/options/subtype/edit?action=delete&id=[id]&reset=1',
+ ];
+
/**
* Contact Type ID
*
<adminGroup>Customize Data and Screens</adminGroup>
<weight>40</weight>
</item>
+ <item>
+ <path>civicrm/admin/options/subtype/edit</path>
+ <title>Edit Contact Type</title>
+ <page_callback>CRM_Admin_Form_ContactType</page_callback>
+ </item>
<item>
<path>civicrm/admin/options/gender</path>
<title>Gender Options</title>
'fa-picture-o'
);
foreach ($contactTypesWithImages as $contactType) {
- $message->addAction($contactType['label'], FALSE, 'href', ['path' => 'civicrm/admin/options/subtype', 'query' => ['action' => 'update', 'id' => $contactType['id'], 'reset' => 1]], 'fa-pencil');
+ $message->addAction($contactType['label'], FALSE, 'href', ['path' => 'civicrm/admin/options/subtype/edit', 'query' => ['action' => 'update', 'id' => $contactType['id'], 'reset' => 1]], 'fa-pencil');
}
$messages[] = $message;
}
*
* @see https://docs.civicrm.org/user/en/latest/organising-your-data/contacts/#contact-subtypes
* @see \Civi\Api4\Contact
- * @searchable none
+ * @searchable secondary
* @since 5.19
* @package Civi\Api4
*/
$items = $this->getBatchRecords();
if ($this->getCheckPermissions()) {
+ $idField = CoreUtil::getIdFieldName($this->getEntityName());
foreach ($items as $key => $item) {
- if (!CoreUtil::checkAccessRecord($this, $item, \CRM_Core_Session::getLoggedInContactID() ?: 0)) {
+ // Don't pass the entire item because only the id is a trusted value
+ if (!CoreUtil::checkAccessRecord($this, [$idField => $item[$idField]], \CRM_Core_Session::getLoggedInContactID() ?: 0)) {
throw new UnauthorizedException("ACL check failed");
}
$items[$key]['check_permissions'] = TRUE;
if ($prefix) {
$path = str_replace('[', '[' . $prefix, $path);
}
- // Check access for edit/update links
+ // Check access for edit/update/delete links
// (presumably if a record is shown in SearchKit the user already has view access, and the check is expensive)
if ($path && isset($data) && !in_array($link['action'], ['view', 'preview'], TRUE)) {
$id = $data[$prefix . $idKey] ?? NULL;
$id = is_array($id) ? $id[$index] ?? NULL : $id;
if ($id) {
+ $values = [$idField => $id];
+ // If not aggregated, add other values to help checkAccess be efficient
+ if (!is_array($data[$prefix . $idKey])) {
+ $values += \CRM_Utils_Array::filterByPrefix($data, $prefix);
+ }
$access = civicrm_api4($link['entity'], 'checkAccess', [
// Fudge links with funny action names to check 'update'
'action' => $link['action'] === 'delete' ? 'delete' : 'update',
- 'values' => [
- $idField => $id,
- ],
+ 'values' => $values,
], 0)['access'];
if (!$access) {
return NULL;
<name>civicrm_contact_type</name>
<comment>Provide type information for contacts</comment>
<add>3.1</add>
+ <paths>
+ <add>civicrm/admin/options/subtype/edit?action=add&reset=1</add>
+ <update>civicrm/admin/options/subtype/edit?action=update&id=[id]&reset=1</update>
+ <delete>civicrm/admin/options/subtype/edit?action=delete&id=[id]&reset=1</delete>
+ </paths>
<field>
<name>id</name>
<title>Contact Type ID</title>