Development issueshttps://lab.civicrm.org/groups/dev/-/issues2024-03-20T13:55:38Zhttps://lab.civicrm.org/dev/core/-/issues/5102Allow access to API params from Api4Query2024-03-20T13:55:38ZMichael McAndrewAllow access to API params from Api4QueryContext:
* I am adding an 'extra' calculated field to a spec provider for a custom entity.
* The value of this extra calculated field depends on a parameter passed to the get action.
* I have access to the query in the setSqlRenderer me...Context:
* I am adding an 'extra' calculated field to a spec provider for a custom entity.
* The value of this extra calculated field depends on a parameter passed to the get action.
* I have access to the query in the setSqlRenderer method (which contains a _protected_ API object) but there doesn't appear to be a way to access the API parameters.
Adding the following method to Api4Query allows read only access to API params and seems inline with other methods like `getSelect()`, but feel free to let me know if I am doing it wrong and there is a better approach.
```php
/**
* @return mixed
*/
public function getParam(string $param) {
return call_user_func([$this->api, 'get'.ucfirst($param)]);
}
```
PR coming up...https://lab.civicrm.org/dev/core/-/issues/5062APIv4: Cannot set multi-select ContactRef field that is part of a multi-recor...2024-03-07T15:44:13ZmmyriamAPIv4: Cannot set multi-select ContactRef field that is part of a multi-record custom fieldsetOverview
----------------------------------------
Adding multiple Contact References in a field that is part of a multi-record field set fails with APIv4.
Reproduction steps
----------------------------------------
1. Create a custom f...Overview
----------------------------------------
Adding multiple Contact References in a field that is part of a multi-record field set fails with APIv4.
Reproduction steps
----------------------------------------
1. Create a custom field set for all Individuals and check "Does this Custom Field Set allow multiple records?"
2. Add a ContactRef field and check "Multi-Select"
3. Try to set it via the APIv4 Explorer
![image](/uploads/44ecbf788a66150425e55a9de8a6212f/image.png)
Current behaviour
----------------------------------------
Failing with error:
```
{
"error_code": 0,
"error_message": "value: \u00013\u000193\u0001 is not of the right field data type: ContactReference",
"status": 500
}
```
Environment information
----------------------------------------
https://dmaster.demo.civicrm.org running 5.72.alpha1
Comments
---
Not an issue if the multi-select ContactRef field is not part of a multi-record custom fieldset.https://lab.civicrm.org/dev/core/-/issues/4848Nuance logging on API Authorization fails2023-12-07T00:07:32ZeileenNuance logging on API Authorization failsWhen an api request fails authorization one of 2 things happens
1) too much information is logged to our logs
2) too little information is logged.
In the former case some things like SearchKit rely on authorization failing appropriatel...When an api request fails authorization one of 2 things happens
1) too much information is logged to our logs
2) too little information is logged.
In the former case some things like SearchKit rely on authorization failing appropriately and logging can cause people to spend time debugging & trying to fix issues that are normal operation - ultimately both https://github.com/civicrm/civicrm-core/pull/28259 and https://github.com/civicrm/civicrm-core/pull/28260 fall in this category & nearly wound up opening up security to fix log noise
In the latter case an api call is failing authorization but it is hard to tell where. We recently hit this where the logged output was unhelpful because the backtrace being logged only got as far as the api call - we were not getting the trace from the exception itself (and the fail was happening on something the api called, not the main api). Hence we wound up altering the code to
```
\CRM_Core_Error::backtrace('API Request Authorization failed' . $apiRequest['action'] . " " . $apiRequest['entity'], TRUE);
\CRM_Core_Error::debug_var('backtrace', $e->getTraceAsString());
```
I think that it makes sense to be able to specify at the api call level when you don't care about logging exceptions (ie searchkit) but also to get some more info when you dohttps://lab.civicrm.org/dev/core/-/issues/4733Where art thou APIv4: MailingEventSubscribe Create? Missing parity with civic...2023-11-02T15:16:06Zjustinfreeman (Agileware)Where art thou APIv4: MailingEventSubscribe Create? Missing parity with civicrm_api3('MailingEventSubscribe', 'Create')Where art thou APIv4: MailingEventSubscribe Create? Missing parity with civicrm_api3('MailingEventSubscribe', 'Create')
Agileware Ref: CVAP-50Where art thou APIv4: MailingEventSubscribe Create? Missing parity with civicrm_api3('MailingEventSubscribe', 'Create')
Agileware Ref: CVAP-50https://lab.civicrm.org/dev/core/-/issues/4527End Date field in Relationship cannot filter on date in join clause APIv42023-08-24T21:58:32ZseamusleeEnd Date field in Relationship cannot filter on date in join clause APIv4In APIv4 when joining onto relationships for example from contact.get you cannot use a date value e.g. 2023-08-23 you get unknown field error. However if you put the string into quotes it works
https://dmaster.demo.civicrm.org/civicrm/a...In APIv4 when joining onto relationships for example from contact.get you cannot use a date value e.g. 2023-08-23 you get unknown field error. However if you put the string into quotes it works
https://dmaster.demo.civicrm.org/civicrm/api4#/explorer/Contact/get?join=%5B%5B%22Relationship%20AS%20relationship%22,%22LEFT%22,null,%5B%22id%22,%22%3D%22,%22relationship.contact_id_a%22%5D,%5B%22relationship.end_date%22,%22%3E%22,%222023-08-23%22%5D%5D%5Dhttps://lab.civicrm.org/dev/core/-/issues/4458Error when viewing contact-info profile without "view deleted contacts" permi...2023-08-07T12:11:55ZcolemanwError when viewing contact-info profile without "view deleted contacts" permissionThe change in b7edabe813db467aff6dd1ea083d798089198655 switched the profile to use APIv4 to fetch email id for constructing an email link. The API call looks like this:
```php
$emailID = Email::get()->setOrderBy(['is_primary' => 'DES...The change in b7edabe813db467aff6dd1ea083d798089198655 switched the profile to use APIv4 to fetch email id for constructing an email link. The API call looks like this:
```php
$emailID = Email::get()->setOrderBy(['is_primary' => 'DESC'])->setWhere([['contact_id', '=', $this->_id], ['email', '=', $email], ['on_hold', '=', FALSE], ['contact_id.is_deceased', '=', FALSE], ['contact_id.is_deleted', '=', FALSE], ['contact_id.do_not_email', '=', FALSE]])->execute()->first()['id'];
```
It was reported on SE that this fails for users without "view deleted contacts", however I'm unable to reproduce.
See https://civicrm.stackexchange.com/questions/45313/invalid-field-contact-id-is-deceased-apiv4
This should have already been double-fixed by:
- [Revert "Add permission metadata to contact is_deleted field" #22203](https://github.com/civicrm/civicrm-core/pull/22203)
- [APIv4 - Silently ignore non-permissioned fields instead of throwing exceptions #20724](https://github.com/civicrm/civicrm-core/pull/20724)https://lab.civicrm.org/dev/core/-/issues/4431API4: "!=" has unexpected results on NULL fields2023-07-21T09:59:23ZJonGoldAPI4: "!=" has unexpected results on NULL fieldsOverview
----------------------------------------
Using the `!=` operator when some of the values are `NULL` does not return the `NULL` records.
Reproduction steps
----------------------------------------
1. On a demo site (which by def...Overview
----------------------------------------
Using the `!=` operator when some of the values are `NULL` does not return the `NULL` records.
Reproduction steps
----------------------------------------
1. On a demo site (which by default has no contacts with a subtype), search for contacts that are not of subtype "Parent".
E.g.:
```php
\Civi\Api4\Contact::get(TRUE)
->addWhere('contact_sub_type', '!=', 'Parent')
->execute();
```
Current behaviour
----------------------------------------
No results are returned.
Expected behaviour
----------------------------------------
All results are returned, since no record is a Parent.
Comments
----------------------------------------
I thought at some point, `!=` internally generated `!= and IS NOT NULL` but maybe that was somewhere else.
I just learned about the MySQL null-safe equals operator, which would also solve this problem: https://stackoverflow.com/a/44723097/2832108https://lab.civicrm.org/dev/core/-/issues/4423Slow contact lookup query in SearchKit2023-07-15T12:58:42ZeileenSlow contact lookup query in SearchKitI think we might be doing something weird when we query for an id in search kit / api4
It takes about 30 seconds to return here - that is what I might expect if I was waiting for it to search without an index (ie a pre-pended wildcard) ...I think we might be doing something weird when we query for an id in search kit / api4
It takes about 30 seconds to return here - that is what I might expect if I was waiting for it to search without an index (ie a pre-pended wildcard) but of course we turned that off using the site setting
![image](/uploads/acb69198d4abda193d10b5e2fd103252/image.png)https://lab.civicrm.org/dev/core/-/issues/4412Add something like API 3 Attachments to API 42023-07-06T06:35:00ZlarsssandergreenAdd something like API 3 Attachments to API 4We can't get the full URL for a file from API 4 File and there is no API 4 Attachments, so API 3 must be used — which seems like a significant gap.
Thought this was worth noting as it has come up [twice](https://civicrm.stackexchange.co...We can't get the full URL for a file from API 4 File and there is no API 4 Attachments, so API 3 must be used — which seems like a significant gap.
Thought this was worth noting as it has come up [twice](https://civicrm.stackexchange.com/questions/45209/get-uploaded-file-full-url-via-api-v4/45210) on [SE](https://civicrm.stackexchange.com/questions/45179/civi-crm-apiv4-image-retrieval) recently.https://lab.civicrm.org/dev/core/-/issues/4403SK / API 4 Explorer: event_queue_id, job id, bounce id, etc autocompletes don...2023-07-05T04:30:05ZlarsssandergreenSK / API 4 Explorer: event_queue_id, job id, bounce id, etc autocompletes don't workEdited as this issue is more general than I thought. Fairly minor issue, but:
In SK or API 4 Explorer, for mailing event id fields (event queue id, job id, bounce id, etc), the autocomplete fields don't work. No matter what you input, i...Edited as this issue is more general than I thought. Fairly minor issue, but:
In SK or API 4 Explorer, for mailing event id fields (event queue id, job id, bounce id, etc), the autocomplete fields don't work. No matter what you input, it shows `Loading failed` and you can't make a selection.
To replicate: Choose MailingEventBounce or similar, Where event_queue_id and =.https://lab.civicrm.org/dev/core/-/issues/4354Activities created via API should notify Assignees2023-08-03T12:38:52Zwil_SRQActivities created via API should notify AssigneesOverview
----------------------------------------
If the GUI (https://cc.unidosnow.org/civicrm/activity?action=add) would notify assignees when an activity is created. It'd be useful for the API to do so too. The GUI respects the setting...Overview
----------------------------------------
If the GUI (https://cc.unidosnow.org/civicrm/activity?action=add) would notify assignees when an activity is created. It'd be useful for the API to do so too. The GUI respects the setting in Administer > Customize Data and Screens > Display Preferences > Notify Activity Assignees and notification rules by Activity type. It'd be useful for the API to do so too.
Example use-case
----------------------------------------
1. Invoke civicrm_api3('Activity', 'create', []) or civicrm_api4('Activity', 'create', [])
2. Include assignees
Current behaviour
----------------------------------------
The Activity is created but the assignees are not notified, even in situations where creating the equivalent activity via the GUI would have issued notifications.
Proposed behaviour
----------------------------------------
Notify assignees using the same rules and notification format as the GUI.
Comments
----------------------------------------
See https://civicrm.stackexchange.com/q/45078/5446
Workaround is to call CRM_Activity_BAO_Activity::sendToAssignee() separatelyhttps://lab.civicrm.org/dev/core/-/issues/4320API: Should NOT operators return NULL values?2023-07-13T23:50:59ZlarsssandergreenAPI: Should NOT operators return NULL values?If you do != 5 in SQL, you'll get all rows that aren't 5, not including null values. This is the same in the API and SearchKit. I wonder if this is the desired behaviour? I would think the assumption would be that if I search for all Con...If you do != 5 in SQL, you'll get all rows that aren't 5, not including null values. This is the same in the API and SearchKit. I wonder if this is the desired behaviour? I would think the assumption would be that if I search for all Contributions where the Contribution Page is != 5, I would get all Contributions except those that have Contribution Page = 5 — but what I actually get is all Contributions that have a Contribution Page, but where that Contribution Page isn't 5.
In other words, I think you'd generally expect that if you search all Contributions where Contribution Page = 5 OR Contribution Page != 5, you'd just get all Contributions, but you only get Contributions with a Contribution Page. Obviously, your expectation might change based on your familiarity with SQL.
This is the same for NOT LIKE, NOT REGEX, and so on.
On the one hand, it's generally better to keep the behaviour of the API operators the same as SQL to avoid confusion. On the other hand, I'm having a hard time imagining a search you might want to make with a NOT that you wouldn't want to include null values, so this seems unhelpful and potentially frustrating. Is this something we should consider changing?https://lab.civicrm.org/dev/core/-/issues/4226Mapping.mapping_id does not resolve in api v4 explorer2023-04-12T07:28:35ZeileenMapping.mapping_id does not resolve in api v4 explorer@colemanw what is the right approach here - there is a foreign key - but civicrm_mapping only has name, not label etc -(I kinda see this table being deprecated over time too)
![image](/uploads/618ea8286b9b6792ccad8de319ff311f/image.png)...@colemanw what is the right approach here - there is a foreign key - but civicrm_mapping only has name, not label etc -(I kinda see this table being deprecated over time too)
![image](/uploads/618ea8286b9b6792ccad8de319ff311f/image.png)
```
<field>
<name>mapping_id</name>
<type>int unsigned</type>
<title>Mapping ID</title>
<required>true</required>
<comment>Mapping to which this field belongs</comment>
<html>
<label>Mapping</label>
</html>
<add>1.2</add>
</field>
<foreignKey>
<name>mapping_id</name>
<table>civicrm_mapping</table>
<key>id</key>
<add>1.2</add>
<onDelete>CASCADE</onDelete>
</foreignKey>
```https://lab.civicrm.org/dev/core/-/issues/4199SearchKit: DB Error: no such field a.total_amount when adding Tax Exclusive A...2023-03-24T03:46:42ZherbdoolSearchKit: DB Error: no such field a.total_amount when adding Tax Exclusive Amount and Balance (starting with Line Items : Contributions)Overview
----------------------------------------
There's an "Unknown column `a.total_amount` when trying to add these fields onto a SearchKit search that starts with `Line Items` and with `Contributions`:
Line Item Contribution: Tax Ex...Overview
----------------------------------------
There's an "Unknown column `a.total_amount` when trying to add these fields onto a SearchKit search that starts with `Line Items` and with `Contributions`:
Line Item Contribution: Tax Exclusive Amount
Line Item Contribution: Balance
**Note this only happens when starting with Line Items and *not* when starting with Contributions (and optionally adding Line Items).**
It's adding a field like this:
```
COALESCE(a.total_amount, 0) - COALESCE(a.tax_amount, 0) AS `LineItem_Contribution_contribution_id_01.tax_exclusive_amount`
```
and like this:
```
a.total_amount - COALESCE((SELECT SUM(ft.total_amount) FROM civicrm_financial_trxn ft
INNER JOIN civicrm_entity_financial_trxn eft ON (eft.financial_trxn_id = ft.id AND eft.entity_table = 'civicrm_contribution')
WHERE eft.entity_id = a.id AND ft.is_payment = 1 AND ft.status_id IN (1,7)), 0) AS `LineItem_Contribution_contribution_id_01.balance_amount`
```
where `a` is `civicrm_line_item`. It's assuming, I think, that the first table is `civicrm_contributions`.
Current behaviour
----------------------------------------
_What happens currently. Please provide error messages, screenshots or gifs ([LICEcap](http://www.cockos.com/licecap/), [SilentCast](https://github.com/colinkeenan/silentcast)) where appropriate._
Environment information
----------------------------------------
* __CiviCRM:__ 5.58.1 (but I looked through the release notes and I don't think it was fixed in 5.59.x)https://lab.civicrm.org/dev/core/-/issues/4182Create a generic copy or clone api2023-03-17T07:50:37ZeileenCreate a generic copy or clone apiThis is a spin off of https://lab.civicrm.org/dev/core/-/issues/4130
I was looking at supporting import job templates & thought a clone or copy api makes sense.
I'm no longer prioritising this part & I think putting the code in the fo...This is a spin off of https://lab.civicrm.org/dev/core/-/issues/4130
I was looking at supporting import job templates & thought a clone or copy api makes sense.
I'm no longer prioritising this part & I think putting the code in the form layer or BAO layer for the specific entity is enouugh for now.
In order to clone the job the code looks something like
```
$userJob = UserJob::get()->addWhere('id', '=', $templateID)->execute()->first();
unset($userJob['metadata']['DataSource']['table_name'], $userJob['metadata']['submitted_values']['uploadFile'], $userJob['id'], $userJob['created_id'], $userJob['created_date'], $userJob['expires_date']);
$userJobID = UserJob::create(FALSE)->setValues($userJob)->execute()->first()['id'];
```
I feel like there is a case for a generic `Copy` api - in the `DAO` we have [a function with a signature that I think is probably 'a bit much'](https://github.com/civicrm/civicrm-core/blob/8bf6c5853cf76da43765cd8ef79d4323a442f350/CRM/Core/DAO.php#L1845-L1868) - so it might make sense to migrate to a new function... & create a generic API
I checked what Entities implement `Copy` and found a handful -the non static ones are not in the BAO - so we just have one non-std signature which is unused https://github.com/civicrm/civicrm-core/pull/25594
![image](/uploads/c4e1bbdf63fb79efaa06b03bca44fde4/image.png)
One option would be to add a parameter to the schema eg.
'is_not_clonable'
And then we could add that to fields like `created_id` and they would not need to be in the params. We already have the title of the entity so can assume that should be prefixed with `Copy Of`. The `UserJob` would have to override to set some of the deeper valueshttps://lab.civicrm.org/dev/core/-/issues/4141API4: When searching by date range, end of range is not included2023-04-22T17:05:33ZlarsssandergreenAPI4: When searching by date range, end of range is not includedWhen you use SearchKit to search by date range on a datetime field (i.e. between two dates), the end date is not included in the results because it interprets 12/31/2022 as 20221231000000 instead of the expected 20221231235959. The same ...When you use SearchKit to search by date range on a datetime field (i.e. between two dates), the end date is not included in the results because it interprets 12/31/2022 as 20221231000000 instead of the expected 20221231235959. The same happens in FormBuilder with a date filter and Choose date range. This comes from API4, where `->addWhere('receive_date', 'BETWEEN', ['2022-01-01', '2022-12-31'])` is interpreted as to 20221231000000 rather than to 20221231235959.
This is quite confusing for users, e.g. when last quarter doesn't give the same results as 10/01/2022 - 12/31/2022.
I think the fix is simply to use a default time of 23:59:59 if none is specified for an end date, but I'm not sure if that might cause unexpected behaviour elsewhere.https://lab.civicrm.org/dev/core/-/issues/4129API v4 explorer: boolean params don't render correctly for CV (short)2023-02-20T06:24:39ZnoahAPI v4 explorer: boolean params don't render correctly for CV (short)The API4 explorer generates shorthand `cv` syntax that looks like, for example:
````bash
cv api4 Contact.delete +w 'id = 99' checkPermissions=false useTrash=false
````
However, `cv` does not correctly interpret `false` in this context....The API4 explorer generates shorthand `cv` syntax that looks like, for example:
````bash
cv api4 Contact.delete +w 'id = 99' checkPermissions=false useTrash=false
````
However, `cv` does not correctly interpret `false` in this context. The syntax that works is:
````bash
cv api4 Contact.delete +w 'id = 99' checkPermissions=0 useTrash=0
````
So the explorer should generate that syntax.https://lab.civicrm.org/dev/core/-/issues/4117Filter Searches by 'is_current' / expires_date2023-02-07T23:27:08ZeileenFilter Searches by 'is_current' / expires_dateThe `civicrm_search` table has an `expires_date` field. I believe it should be used as a filter on the search admin screen.
I copied the field into `civicrm_user_job` when I created that and the searches based on user jobs have expires_...The `civicrm_search` table has an `expires_date` field. I believe it should be used as a filter on the search admin screen.
I copied the field into `civicrm_user_job` when I created that and the searches based on user jobs have expires_date set from the user job.
I realised it is a bit of a pain to add to the js as it would be `expires_date` is in the past OR is NULL - which got me thinking that it is most like `is_current` & perhaps should be a trait like that - with is_current = TRUE as a default
@colemanw - what has me most confused is where to put it - I could add it to `IsCurrentSpecProvider` & it just has different rules - maybe I'll tryhttps://lab.civicrm.org/dev/core/-/issues/4110Can't edit Activity source, targets, assignees in FormBuilder2023-04-05T16:48:01ZnoahCan't edit Activity source, targets, assignees in FormBuilder[As reported](https://chat.civicrm.org/civicrm/pl/eprjkpg4cbrcbbj7u64qnbsohc) by @guyiac on MM:
I'm trying to use a form to edit existing activities. I can pass the existing activity id successfully with an URL, and all the information ...[As reported](https://chat.civicrm.org/civicrm/pl/eprjkpg4cbrcbbj7u64qnbsohc) by @guyiac on MM:
I'm trying to use a form to edit existing activities. I can pass the existing activity id successfully with an URL, and all the information for the activity will pre-fill into the form, ***except*** the contacts (targets, assigned to, and created by). Am I missing something? Civi 5.54.0.https://lab.civicrm.org/dev/core/-/issues/4051ApiV4 - add options2022-12-27T20:14:54ZeileenApiV4 - add options@totten has added something to `cv` where you can add an option to an existing field - I think this feature makes sense, but as a an apiv4 feature (rather than a cv feature) and across multiple entities rather than just Settings. There a...@totten has added something to `cv` where you can add an option to an existing field - I think this feature makes sense, but as a an apiv4 feature (rather than a cv feature) and across multiple entities rather than just Settings. There are different ways it could look but in essence you are looking to be able to offer stuff like
```
Setting::update()->addWhere('name', '=', 'enable_components')->addOption(['CiviCampaign'])->execute();
Setting::update()->addWhere('name', '=', 'enable_components')->removeOption(['CiviCampaign'])->execute();
Contact::update()->addWhere('id', '=', 123)->addOption(['contact_sub_type' => 'Student'])->execute();
Contact::update()->addWhere('id', '=', 123)->removeOption(['contact_sub_type' => 'Student'])->execute();
```
I'm not sure the exact syntax or whether it should be on the `update` action - one for @colemanw
- This would probably be limited to fields with `is_multiple` or `serialize` or some other indicator of multiple-value-ness (whatever we land on for settings) & be validated against the relevant pseudoconstant or callback-option-list