diff --git a/CRM/ACL/BAO/ACL.php b/CRM/ACL/BAO/ACL.php index c3dee1f46082..8ab4959f13ba 100644 --- a/CRM/ACL/BAO/ACL.php +++ b/CRM/ACL/BAO/ACL.php @@ -9,6 +9,8 @@ +--------------------------------------------------------------------+ */ +use Civi\Api4\Utils\CoreUtil; + /** * * @package CRM @@ -529,4 +531,45 @@ private static function getGroupClause(array $groupIDs, string $operation): stri return ''; } + public static function getObjectTableOptions(): array { + return [ + 'civicrm_group' => ts('Group'), + 'civicrm_uf_group' => ts('Profile'), + 'civicrm_event' => ts('Event'), + 'civicrm_custom_group' => ts('Custom Group'), + ]; + } + + public static function getObjectIdOptions($context, $params): array { + if (empty($params['values']['object_table']) && empty($params['values']['object_table:label'])) { + return []; + } + if (!empty($params['values']['object_table:label'])) { + $table_name = array_flip(self::getObjectTableOptions())[$params['values']['object_table:label']]; + } + else { + $table_name = $params['values']['object_table']; + } + $finalOptions = []; + $entity = CoreUtil::getApiNameFromTableName($table_name); + $label = CoreUtil::getInfoItem($entity, 'label_field'); + $titlePlural = CoreUtil::getInfoItem($entity, 'title_plural'); + $finalOptions[] = [ + 'label' => ts('All %1', [1 => $titlePlural]), + 'id' => 0, + 'name' => 0, + ]; + $options = civicrm_api4($entity, 'get', [ + 'select' => [$label, 'id', 'name'], + ]); + foreach ($options as $option) { + $finalOptions[] = [ + 'label' => $option[$label], + 'id' => $option['id'], + 'name' => $option['name'] ?? $option['id'], + ]; + } + return $finalOptions; + } + } diff --git a/CRM/ACL/DAO/ACL.php b/CRM/ACL/DAO/ACL.php index 9683d71d3c78..ac13bb14c914 100644 --- a/CRM/ACL/DAO/ACL.php +++ b/CRM/ACL/DAO/ACL.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/ACL/ACL.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:689e7e5f58bb2cc9959817ecbbd3beeb) + * (GenCodeChecksum:79ed87b3613a7a626f02242218256dd1) */ /** @@ -294,6 +294,10 @@ public static function &fields() { 'entity' => 'ACL', 'bao' => 'CRM_ACL_BAO_ACL', 'localizable' => 0, + 'pseudoconstant' => [ + 'optionGroupName' => 'acl_role', + 'optionEditPath' => 'civicrm/admin/options/acl_role', + ], 'add' => '1.6', ], 'operation' => [ @@ -341,6 +345,9 @@ public static function &fields() { 'entity' => 'ACL', 'bao' => 'CRM_ACL_BAO_ACL', 'localizable' => 0, + 'pseudoconstant' => [ + 'callback' => 'CRM_ACL_BAO_ACL::getObjectTableOptions', + ], 'add' => '1.6', ], 'object_id' => [ @@ -359,6 +366,10 @@ public static function &fields() { 'entity' => 'ACL', 'bao' => 'CRM_ACL_BAO_ACL', 'localizable' => 0, + 'pseudoconstant' => [ + 'callback' => 'CRM_ACL_BAO_ACL::getObjectIdOptions', + 'prefetch' => 'false', + ], 'add' => '1.6', ], 'acl_table' => [ diff --git a/CRM/ACL/Form/ACL.php b/CRM/ACL/Form/ACL.php index 3f65d8d7bcbd..7282113225a0 100644 --- a/CRM/ACL/Form/ACL.php +++ b/CRM/ACL/Form/ACL.php @@ -132,7 +132,6 @@ public function buildQuickForm() { $label = ts('Role'); $role = [ '-1' => ts('- select role -'), - '0' => ts('Everyone'), ] + CRM_Core_OptionGroup::values('acl_role'); $this->add('select', 'entity_id', $label, $role, TRUE); diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index 77dba37b849d..6d8375861b13 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -2776,17 +2776,17 @@ public static function appendPseudoConstantsToFields(&$fields) { * @param string $fieldName * @param string $context * @see CRM_Core_DAO::buildOptionsContext - * @param array $props + * @param array $values * Raw field values; whatever is known about this bao object. * * Note: $props can contain unsanitized input and should not be passed directly to CRM_Core_PseudoConstant::get * * @return array|bool */ - public static function buildOptions($fieldName, $context = NULL, $props = []) { + public static function buildOptions($fieldName, $context = NULL, $values = []) { // If a given bao does not override this function $baoName = get_called_class(); - return CRM_Core_PseudoConstant::get($baoName, $fieldName, [], $context); + return CRM_Core_PseudoConstant::get($baoName, $fieldName, ['values' => $values], $context); } /** diff --git a/CRM/Upgrade/Incremental/php/FiveSixtyFour.php b/CRM/Upgrade/Incremental/php/FiveSixtyFour.php index fdd22f175764..10d18a85d0b9 100644 --- a/CRM/Upgrade/Incremental/php/FiveSixtyFour.php +++ b/CRM/Upgrade/Incremental/php/FiveSixtyFour.php @@ -31,6 +31,7 @@ public function upgrade_5_64_alpha1($rev): void { $this->addTask('Add priority column onto ACL table', 'addColumn', 'civicrm_acl', 'priority', 'int NOT NULL DEFAULT 0'); $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev); $this->addTask('Update post_URL/cancel_URL in logging tables', 'updateLogging'); + $this->addTask('Add in Everybody ACL Role option value', 'addEveryBodyAclOptionValue'); } public static function updateLogging($ctx): bool { @@ -44,4 +45,16 @@ public static function updateLogging($ctx): bool { return TRUE; } + public static function addEverybodyAclOptionValue($ctx): bool { + \CRM_Core_BAO_OptionValue::ensureOptionValueExists([ + 'label' => 'Everybody', + 'value' => 0, + 'option_group_id' => 'acl_role', + 'is_active' => 1, + 'name' => 'Everybody', + 'is_reserved' => 1, + ]); + return TRUE; + } + } diff --git a/Civi/Api4/ACL.php b/Civi/Api4/ACL.php index 76c009424cfd..2416179ee080 100644 --- a/Civi/Api4/ACL.php +++ b/Civi/Api4/ACL.php @@ -23,7 +23,6 @@ * * Creating a new ACL requires at minimum an entity table, entity ID and object_table. * - * @searchable none * @see https://docs.civicrm.org/user/en/latest/initial-set-up/permissions-and-access-control * @since 5.19 * @orderBy priority diff --git a/ext/civicrm_admin_ui/ang/afsearchManageACLs.aff.html b/ext/civicrm_admin_ui/ang/afsearchManageACLs.aff.html new file mode 100644 index 000000000000..4864c1fd40cd --- /dev/null +++ b/ext/civicrm_admin_ui/ang/afsearchManageACLs.aff.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/ext/civicrm_admin_ui/ang/afsearchManageACLs.aff.json b/ext/civicrm_admin_ui/ang/afsearchManageACLs.aff.json new file mode 100644 index 000000000000..9c7f2567ab67 --- /dev/null +++ b/ext/civicrm_admin_ui/ang/afsearchManageACLs.aff.json @@ -0,0 +1,8 @@ +{ + "type": "search", + "title": "Manage ACLs", + "icon": "fa-list-alt", + "server_route": "civicrm/acl", + "permission": "administer CiviCRM", + "navigation": null +} diff --git a/ext/civicrm_admin_ui/managed/SavedSearch_Manage_ACLs.mgd.php b/ext/civicrm_admin_ui/managed/SavedSearch_Manage_ACLs.mgd.php new file mode 100644 index 000000000000..35bff4ca2042 --- /dev/null +++ b/ext/civicrm_admin_ui/managed/SavedSearch_Manage_ACLs.mgd.php @@ -0,0 +1,179 @@ + 'SavedSearch_Manage_ACLs', + 'entity' => 'SavedSearch', + 'cleanup' => 'unused', + 'update' => 'unmodified', + 'params' => [ + 'version' => 4, + 'values' => [ + 'name' => 'Manage_ACLs', + 'label' => E::ts('Manage ACLs'), + 'form_values' => NULL, + 'mapping_id' => NULL, + 'search_custom_id' => NULL, + 'api_entity' => 'ACL', + 'api_params' => [ + 'version' => 4, + 'select' => [ + 'entity_id:label', + 'operation:label', + 'object_table:label', + 'object_id:label', + 'name', + 'is_active', + 'deny', + 'priority', + ], + 'orderBy' => [], + 'where' => [], + 'groupBy' => [], + 'join' => [], + 'having' => [], + ], + 'expires_date' => NULL, + 'description' => NULL, + ], + 'match' => [ + 'name', + ], + ], + ], + [ + 'name' => 'SavedSearch_Manage_ACLs_SearchDisplay_Manage_ACLs_Table_1', + 'entity' => 'SearchDisplay', + 'cleanup' => 'unused', + 'update' => 'unmodified', + 'params' => [ + 'version' => 4, + 'values' => [ + 'name' => 'Manage_ACLs_Table_1', + 'label' => E::ts('Manage ACLs'), + 'saved_search_id.name' => 'Manage_ACLs', + 'type' => 'table', + 'settings' => [ + 'description' => NULL, + 'sort' => [ + [ + 'priority', + 'ASC', + ], + ], + 'limit' => 50, + 'pager' => [], + 'placeholder' => 5, + 'columns' => [ + [ + 'type' => 'field', + 'key' => 'entity_id:label', + 'dataType' => 'Integer', + 'label' => E::ts('Role'), + 'sortable' => TRUE, + ], + [ + 'type' => 'field', + 'key' => 'operation:label', + 'dataType' => 'String', + 'label' => E::ts('Operation'), + 'sortable' => TRUE, + ], + [ + 'type' => 'field', + 'key' => 'object_table:label', + 'dataType' => 'String', + 'label' => E::ts('Type of Data'), + 'sortable' => TRUE, + ], + [ + 'type' => 'field', + 'key' => 'object_id:label', + 'dataType' => 'Integer', + 'label' => E::ts('Which Data'), + 'sortable' => TRUE, + ], + [ + 'type' => 'field', + 'key' => 'name', + 'dataType' => 'String', + 'label' => E::ts('Description'), + 'sortable' => TRUE, + ], + [ + 'type' => 'field', + 'key' => 'is_active', + 'dataType' => 'Boolean', + 'label' => E::ts('Enabled'), + 'sortable' => TRUE, + ], + [ + 'type' => 'field', + 'key' => 'deny', + 'dataType' => 'Boolean', + 'label' => E::ts('Mode'), + 'sortable' => TRUE, + 'rewrite' => '{if "[deny]" eq "1"}' . E::ts('Deny') . '{else}' . E::ts('Allow') . '{/if}', + ], + [ + 'type' => 'field', + 'key' => 'priority', + 'dataType' => 'Integer', + 'label' => E::ts('Priority'), + 'sortable' => TRUE, + ], + [ + 'text' => '', + 'style' => 'default', + 'size' => 'btn-xs', + 'icon' => 'fa-bars', + 'links' => [ + [ + 'entity' => 'ACL', + 'action' => 'update', + 'join' => '', + 'target' => 'crm-popup', + 'icon' => 'fa-pencil', + 'text' => E::ts('Edit ACL'), + 'style' => 'default', + 'path' => '', + 'condition' => [], + ], + [ + 'entity' => 'ACL', + 'action' => 'delete', + 'join' => '', + 'target' => 'crm-popup', + 'icon' => 'fa-trash', + 'text' => E::ts('Delete ACL'), + 'style' => 'danger', + 'path' => '', + 'condition' => [], + ], + ], + 'type' => 'menu', + 'alignment' => 'text-right', + ], + ], + 'actions' => TRUE, + 'classes' => [ + 'table', + 'table-striped', + ], + 'addButton' => [ + 'path' => 'civicrm/acl/edit?reset=1&action=add', + 'text' => E::ts('Add ACL'), + 'icon' => 'fa-plus', + ], + ], + 'acl_bypass' => FALSE, + ], + 'match' => [ + 'name', + 'saved_search_id', + ], + ], + ], +]; diff --git a/tests/phpunit/api/v3/SyntaxConformanceTest.php b/tests/phpunit/api/v3/SyntaxConformanceTest.php index e580a495ec74..2506f0bb9783 100644 --- a/tests/phpunit/api/v3/SyntaxConformanceTest.php +++ b/tests/phpunit/api/v3/SyntaxConformanceTest.php @@ -1453,7 +1453,9 @@ public function testCreateSingleValueAlter($entityName): void { $options[$optionValue[0][$keyColumn]] = 'new option value'; } } - $entity[$field] = array_rand($options); + if ($options) { + $entity[$field] = array_rand($options); + } } if (!empty($specs['FKClassName']) && !empty($specs['pseudoconstant'])) { // in the weird situation where a field has both an fk and pseudoconstant defined, diff --git a/xml/schema/ACL/ACL.xml b/xml/schema/ACL/ACL.xml index b054c68777fd..8cb4dbbfb8ef 100644 --- a/xml/schema/ACL/ACL.xml +++ b/xml/schema/ACL/ACL.xml @@ -63,6 +63,9 @@ int unsigned Entity ID ID of the object possessing this ACL + + acl_role + 1.6 @@ -91,6 +94,9 @@ varchar 64 The table of the object controlled by this ACL entry + + CRM_ACL_BAO_ACL::getObjectTableOptions + 1.6 @@ -99,6 +105,10 @@ int unsigned The ID of the object controlled by this ACL entry 1.6 + + CRM_ACL_BAO_ACL::getObjectIdOptions + false + acl_table