mixin/theme-php - Remove unused boilerplate
[civicrm-core.git] / ext / financialacls / financialacls.php
1 <?php
2
3 require_once 'financialacls.civix.php';
4 // phpcs:disable
5 use CRM_Financialacls_ExtensionUtil as E;
6 // phpcs:enable
7
8 /**
9 * Implements hook_civicrm_config().
10 *
11 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config/
12 */
13 function financialacls_civicrm_config(&$config) {
14 _financialacls_civix_civicrm_config($config);
15 }
16
17 /**
18 * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
19 */
20 function financialacls_civicrm_container($container) {
21 $dispatcherDefn = $container->getDefinition('dispatcher');
22 $container->addResource(new \Symfony\Component\Config\Resource\FileResource(__FILE__));
23 $dispatcherDefn->addMethodCall('addListener', ['civi.api4.authorizeRecord::Contribution', '_financialacls_civi_api4_authorizeContribution']);
24 }
25
26 /**
27 * Implements hook_civicrm_xmlMenu().
28 *
29 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_xmlMenu
30 */
31 function financialacls_civicrm_xmlMenu(&$files) {
32 _financialacls_civix_civicrm_xmlMenu($files);
33 }
34
35 /**
36 * Implements hook_civicrm_install().
37 *
38 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install
39 */
40 function financialacls_civicrm_install() {
41 _financialacls_civix_civicrm_install();
42 }
43
44 /**
45 * Implements hook_civicrm_postInstall().
46 *
47 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall
48 */
49 function financialacls_civicrm_postInstall() {
50 _financialacls_civix_civicrm_postInstall();
51 }
52
53 /**
54 * Implements hook_civicrm_uninstall().
55 *
56 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall
57 */
58 function financialacls_civicrm_uninstall() {
59 _financialacls_civix_civicrm_uninstall();
60 }
61
62 /**
63 * Implements hook_civicrm_enable().
64 *
65 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_enable
66 */
67 function financialacls_civicrm_enable() {
68 _financialacls_civix_civicrm_enable();
69 }
70
71 /**
72 * Implements hook_civicrm_disable().
73 *
74 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable
75 */
76 function financialacls_civicrm_disable() {
77 _financialacls_civix_civicrm_disable();
78 }
79
80 /**
81 * Implements hook_civicrm_upgrade().
82 *
83 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade
84 */
85 function financialacls_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
86 return _financialacls_civix_civicrm_upgrade($op, $queue);
87 }
88
89 /**
90 * Implements hook_civicrm_managed().
91 *
92 * Generate a list of entities to create/deactivate/delete when this module
93 * is installed, disabled, uninstalled.
94 *
95 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_managed
96 */
97 function financialacls_civicrm_managed(&$entities) {
98 _financialacls_civix_civicrm_managed($entities);
99 }
100
101 /**
102 * Implements hook_civicrm_caseTypes().
103 *
104 * Generate a list of case-types.
105 *
106 * Note: This hook only runs in CiviCRM 4.4+.
107 *
108 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_caseTypes
109 */
110 function financialacls_civicrm_caseTypes(&$caseTypes) {
111 _financialacls_civix_civicrm_caseTypes($caseTypes);
112 }
113
114 /**
115 * Implements hook_civicrm_entityTypes().
116 *
117 * Declare entity types provided by this module.
118 *
119 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes
120 */
121 function financialacls_civicrm_entityTypes(&$entityTypes) {
122 _financialacls_civix_civicrm_entityTypes($entityTypes);
123 }
124
125 /**
126 * Intervene to prevent deletion, where permissions block it.
127 *
128 * @param string $op
129 * @param string $objectName
130 * @param int|null $id
131 * @param array $params
132 *
133 * @throws \API_Exception
134 * @throws \CRM_Core_Exception
135 */
136 function financialacls_civicrm_pre($op, $objectName, $id, &$params) {
137 if (!financialacls_is_acl_limiting_enabled()) {
138 return;
139 }
140 if ($objectName === 'LineItem' && !empty($params['check_permissions'])) {
141 $operationMap = ['delete' => CRM_Core_Action::DELETE, 'edit' => CRM_Core_Action::UPDATE, 'create' => CRM_Core_Action::ADD];
142 CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($types, $operationMap[$op]);
143 if (empty($params['financial_type_id'])) {
144 $params['financial_type_id'] = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_LineItem', $params['id'], 'financial_type_id');
145 }
146 if (!array_key_exists($params['financial_type_id'], $types)) {
147 throw new API_Exception('You do not have permission to ' . $op . ' this line item');
148 }
149 }
150 if ($objectName === 'FinancialType' && !empty($params['id']) && !empty($params['name'])) {
151 $prevName = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType', $params['id']);
152 if ($prevName !== $params['name']) {
153 CRM_Core_Session::setStatus(ts("Changing the name of a Financial Type will result in losing the current permissions associated with that Financial Type.
154 Before making this change you should likely note the existing permissions at Administer > Users and Permissions > Permissions (Access Control),
155 then clicking the Access Control link for your Content Management System, then noting down the permissions for 'CiviCRM: {financial type name} view', etc.
156 Then after making the change of name, reset the permissions to the way they were."), ts('Warning'), 'warning');
157 }
158 }
159 }
160
161 /**
162 * Implements hook_civicrm_selectWhereClause().
163 *
164 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_selectWhereClause
165 */
166 function financialacls_civicrm_selectWhereClause($entity, &$clauses) {
167 if (!financialacls_is_acl_limiting_enabled()) {
168 return;
169 }
170
171 switch ($entity) {
172 case 'LineItem':
173 case 'MembershipType':
174 case 'ContributionRecur':
175 $types = [];
176 CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($types);
177 if ($types) {
178 $clauses['financial_type_id'] = 'IN (' . implode(',', array_keys($types)) . ')';
179 }
180 else {
181 $clauses['financial_type_id'] = '= 0';
182 }
183 break;
184
185 }
186
187 }
188
189 /**
190 * Remove unpermitted options.
191 *
192 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_buildAmount
193 *
194 * @param string $component
195 * @param \CRM_Core_Form $form
196 * @param array $feeBlock
197 */
198 function financialacls_civicrm_buildAmount($component, $form, &$feeBlock) {
199 if (!financialacls_is_acl_limiting_enabled()) {
200 return;
201 }
202
203 foreach ($feeBlock as $key => $value) {
204 foreach ($value['options'] as $k => $options) {
205 if (!CRM_Core_Permission::check('add contributions of type ' . CRM_Contribute_PseudoConstant::financialType($options['financial_type_id']))) {
206 unset($feeBlock[$key]['options'][$k]);
207 }
208 }
209 if (empty($feeBlock[$key]['options'])) {
210 unset($feeBlock[$key]);
211 }
212 }
213 }
214
215 /**
216 * Remove unpermitted membership types from selection availability..
217 *
218 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_membershipTypeValues
219 *
220 * @param \CRM_Core_Form $form
221 * @param array $membershipTypeValues
222 */
223 function financialacls_civicrm_membershipTypeValues($form, &$membershipTypeValues) {
224 if (!financialacls_is_acl_limiting_enabled()) {
225 return;
226 }
227 $financialTypes = NULL;
228 $financialTypes = CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes, CRM_Core_Action::ADD);
229 foreach ($membershipTypeValues as $id => $type) {
230 if (!isset($financialTypes[$type['financial_type_id']])) {
231 unset($membershipTypeValues[$id]);
232 }
233 }
234 }
235
236 /**
237 * Add permissions.
238 *
239 * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_permission/
240 *
241 * @param array $permissions
242 */
243 function financialacls_civicrm_permission(&$permissions) {
244 if (!financialacls_is_acl_limiting_enabled()) {
245 return;
246 }
247 $actions = [
248 'add' => ts('add'),
249 'view' => ts('view'),
250 'edit' => ts('edit'),
251 'delete' => ts('delete'),
252 ];
253 $financialTypes = \CRM_Contribute_BAO_Contribution::buildOptions('financial_type_id', 'validate');
254 foreach ($financialTypes as $id => $type) {
255 foreach ($actions as $action => $action_ts) {
256 $permissions[$action . ' contributions of type ' . $type] = [
257 ts("CiviCRM: %1 contributions of type %2", [1 => $action_ts, 2 => $type]),
258 ts('%1 contributions of type %2', [1 => $action_ts, 2 => $type]),
259 ];
260 }
261 }
262 $permissions['administer CiviCRM Financial Types'] = [
263 ts('CiviCRM: administer CiviCRM Financial Types'),
264 ts('Administer access to Financial Types'),
265 ];
266 }
267
268 /**
269 * Listener for 'civi.api4.authorizeRecord::Contribution'
270 *
271 * @param \Civi\Api4\Event\AuthorizeRecordEvent $e
272 * @throws \CRM_Core_Exception
273 */
274 function _financialacls_civi_api4_authorizeContribution(\Civi\Api4\Event\AuthorizeRecordEvent $e) {
275 if (!financialacls_is_acl_limiting_enabled()) {
276 return;
277 }
278 if ($e->getEntityName() === 'Contribution') {
279 $contributionID = $e->getRecord()['id'] ?? NULL;
280 $financialTypeID = $e->getRecord()['financial_type_id'] ?? CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionID, 'financial_type_id');
281 if (!CRM_Core_Permission::check(_financialacls_getRequiredPermission($financialTypeID, $e->getActionName()), $e->getUserID())) {
282 $e->setAuthorized(FALSE);
283 }
284 if ($e->getActionName() === 'delete') {
285 // First check contribution financial type
286 // Now check permissioned line items & permissioned contribution
287 if (!CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($contributionID, 'delete', FALSE, $e->getUserID())
288 ) {
289 $e->setAuthorized(FALSE);
290 }
291 }
292 }
293 }
294
295 /**
296 * Get the permission required to perform this action on this financial type.
297 *
298 * @param int $financialTypeID
299 * @param string $action
300 *
301 * @return string
302 */
303 function _financialacls_getRequiredPermission(int $financialTypeID, string $action): string {
304 $financialType = CRM_Core_PseudoConstant::getName('CRM_Contribute_DAO_Contribution', 'financial_type_id', $financialTypeID);
305 $actionMap = [
306 'create' => 'add',
307 'update' => 'edit',
308 'delete' => 'delete',
309 ];
310 return $actionMap[$action] . ' contributions of type ' . $financialType;
311 }
312
313 /**
314 * Remove unpermitted financial types from field Options in search context.
315 *
316 * Search context is described as
317 * 'search' => "search: searchable options are returned; labels are translated.",
318 * So this is appropriate to removing the options from search screens.
319 *
320 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_fieldOptions
321 *
322 * @param string $entity
323 * @param string $field
324 * @param array $options
325 * @param array $params
326 */
327 function financialacls_civicrm_fieldOptions($entity, $field, &$options, $params) {
328 if (!financialacls_is_acl_limiting_enabled()) {
329 return;
330 }
331 if (in_array($entity, ['Contribution', 'ContributionRecur'], TRUE) && $field === 'financial_type_id' && $params['context'] === 'search') {
332 $action = CRM_Core_Action::VIEW;
333 // At this stage we are only considering the view action. Code from
334 // CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes().
335 $actions = [
336 CRM_Core_Action::VIEW => 'view',
337 CRM_Core_Action::UPDATE => 'edit',
338 CRM_Core_Action::ADD => 'add',
339 CRM_Core_Action::DELETE => 'delete',
340 ];
341 $cacheKey = 'available_types_' . $action;
342 if (!isset(\Civi::$statics['CRM_Financial_BAO_FinancialType'][$cacheKey])) {
343 foreach ($options as $finTypeId => $type) {
344 if (!CRM_Core_Permission::check($actions[$action] . ' contributions of type ' . $type)) {
345 unset($options[$finTypeId]);
346 }
347 }
348 \Civi::$statics['CRM_Financial_BAO_FinancialType'][$cacheKey] = $options;
349 }
350 $options = \Civi::$statics['CRM_Financial_BAO_FinancialType'][$cacheKey];
351 }
352 }
353
354 /**
355 * Is financial acl limiting enabled.
356 *
357 * Once this extension is detangled enough to be optional this will go
358 * and the status of the extension rather than the setting will dictate.
359 *
360 * @return bool
361 */
362 function financialacls_is_acl_limiting_enabled(): bool {
363 return (bool) Civi::settings()->get('acl_financial_type');
364 }
365
366 /**
367 * Clear the statics cache when the setting is enabled or disabled.
368 *
369 * Note the setting will eventually disappear in favour of whether
370 * the extension is enabled or disabled.
371 */
372 function financialacls_toggle() {
373 unset(\Civi::$statics['CRM_Financial_BAO_FinancialType']);
374 }
375
376 // --- Functions below this ship commented out. Uncomment as required. ---
377
378 /**
379 * Implements hook_civicrm_preProcess().
380 *
381 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_preProcess
382 */
383 //function financialacls_civicrm_preProcess($formName, &$form) {
384 //
385 //}
386
387 /**
388 * Implements hook_civicrm_navigationMenu().
389 *
390 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_navigationMenu
391 */
392 //function financialacls_civicrm_navigationMenu(&$menu) {
393 // _financialacls_civix_insert_navigation_menu($menu, 'Mailings', array(
394 // 'label' => E::ts('New subliminal message'),
395 // 'name' => 'mailing_subliminal_message',
396 // 'url' => 'civicrm/mailing/subliminal',
397 // 'permission' => 'access CiviMail',
398 // 'operator' => 'OR',
399 // 'separator' => 0,
400 // ));
401 // _financialacls_civix_navigationMenu($menu);
402 //}