Development issueshttps://lab.civicrm.org/groups/dev/-/issues2020-02-17T02:21:40Zhttps://lab.civicrm.org/dev/core/-/issues/1583API v4 returning incorrect count of contributions under certain WHERE conditions2020-02-17T02:21:40ZjamieAPI v4 returning incorrect count of contributions under certain WHERE conditionsThe database has three contributions with the `contribution_recur_id` set to 19.
When I query for these via apiv4 using just the `contribution_recur_id`, I get three results from the database (and the `first()` function works properly)....The database has three contributions with the `contribution_recur_id` set to 19.
When I query for these via apiv4 using just the `contribution_recur_id`, I get three results from the database (and the `first()` function works properly).
When I query and limit to those with `is_template` set to 1 (there should be no matching results), I get a count of 1, but NULL when I call `first()`.
Here's the data:
```
MariaDB [ptp]> SELECT * FROM civicrm_contribution WHERE contribution_recur_id =19;
+------+------------+-------------------+----------------------+-----------------------+---------------------+-----------------------+--------------+------------+------------+-----------------------------+----------------------------------+----------+-------------+---------------+---------------------+---------------+---------------------------------------------------------------------------------+--------------+-----------------------+---------+--------------+------------------------+------------+--------------+-------------+------------+---------------+--------------------------+----------------+-------------+
| id | contact_id | financial_type_id | contribution_page_id | payment_instrument_id | receive_date | non_deductible_amount | total_amount | fee_amount | net_amount | trxn_id | invoice_id | currency | cancel_date | cancel_reason | receipt_date | thankyou_date | source | amount_level | contribution_recur_id | is_test | is_pay_later | contribution_status_id | address_id | check_number | campaign_id | tax_amount | creditnote_id | revenue_recognition_date | invoice_number | is_template |
+------+------------+-------------------+----------------------+-----------------------+---------------------+-----------------------+--------------+------------+------------+-----------------------------+----------------------------------+----------+-------------+---------------+---------------------+---------------+---------------------------------------------------------------------------------+--------------+-----------------------+---------+--------------+------------------------+------------+--------------+-------------+------------+---------------+--------------------------+----------------+-------------+
| 3928 | 10459 | 2 | 14 | 1 | 2019-12-02 13:07:59 | 0.00 | 296.00 | 8.88 | 287.12 | in_1FlKFWAwDzuDdbFCuWUlA4EZ | 0f3dd1eda0400becb9ecd33c58d28ae8 | USD | NULL | 0 | 2019-12-02 13:07:56 | NULL | Online Contribution: PowerBase Subscription Payment with Monthly Payment Option | NULL | 19 | 0 | 0 | 1 | 24745 | NULL | NULL | NULL | NULL | NULL | NULL | 0 |
| 3951 | 10459 | 2 | 14 | 1 | 2020-01-02 13:08:03 | 0.00 | 296.00 | 8.88 | 287.12 | in_1FwZ1bAwDzuDdbFCXoBfw8UM | NULL | USD | NULL | NULL | 2020-01-02 14:13:42 | NULL | Online Contribution: PowerBase Subscription Payment with Monthly Payment Option | NULL | 19 | 0 | 0 | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 |
| 3999 | 10459 | 2 | 14 | 1 | 2020-02-02 13:08:03 | 0.00 | 296.00 | 8.88 | 287.12 | in_1G7nnbAwDzuDdbFCvncHVNPH | NULL | USD | NULL | NULL | 2020-02-07 15:03:30 | NULL | Online Contribution: PowerBase Subscription Payment with Monthly Payment Option | NULL | 19 | 0 | 0 | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 |
+------+------------+-------------------+----------------------+-----------------------+---------------------+-----------------------+--------------+------------+------------+-----------------------------+----------------------------------+----------+-------------+---------------+---------------------+---------------+---------------------------------------------------------------------------------+--------------+-----------------------+---------+--------------+------------------------+------------+--------------+-------------+------------+---------------+--------------------------+----------------+-------------+
3 rows in set (0.001 sec)
MariaDB [ptp]>
```
Here is the test code:
```
<?php
$res = \Civi\Api4\Contribution::get()
->setCheckPermissions(FALSE)
->addWhere('contribution_recur_id', '=', 19)
->execute();
echo "=== NOTE Results are correct ===\n\n";
echo "count is: " . $res->count() . "\n";
echo "First...\n";
print_r($res->first());
foreach ($res as $r) {
print_r($r);
}
$contribution_recur_id = 19;
$res = \Civi\Api4\Contribution::get()
->setCheckPermissions(FALSE)
->addWhere('contribution_recur_id', '=', 19)
->addWhere('is_template', '=', 1)
->execute();
echo "\n\n";
echo "=== NOTE: count is one, but no results from first() === \n";
echo "count is: " . $res->count() . "\n";
echo "First...\n";
print_r($res->first());
foreach ($res as $r) {
// No output from this call.
print_r($r);
}
```
And here is the output when running that code via `cv`:
```
=== NOTE Results are correct ===
count is: 4
First...
Array
(
[id] => 3928
[contact_id] => 10459
[financial_type_id] => 2
[contribution_page_id] => 14
[payment_instrument_id] => 1
[receive_date] => 2019-12-02 13:07:59
[non_deductible_amount] => 0.00
[total_amount] => 296.00
[fee_amount] => 8.88
[net_amount] => 287.12
[trxn_id] => in_1FlKFWAwDzuDdbFCuWUlA4EZ
[invoice_id] => 0f3dd1eda0400becb9ecd33c58d28ae8
[invoice_number] =>
[currency] => USD
[cancel_date] =>
[cancel_reason] => 0
[receipt_date] => 2019-12-02 13:07:56
[thankyou_date] =>
[source] => Online Contribution: PowerBase Subscription Payment with Monthly Payment Option
[amount_level] =>
[contribution_recur_id] => 19
[is_test] => 0
[is_pay_later] => 0
[contribution_status_id] => 1
[address_id] => 24745
[check_number] =>
[campaign_id] =>
[creditnote_id] =>
[tax_amount] =>
[revenue_recognition_date] =>
[is_template] => 0
)
Array
(
[id] => 3928
[contact_id] => 10459
[financial_type_id] => 2
[contribution_page_id] => 14
[payment_instrument_id] => 1
[receive_date] => 2019-12-02 13:07:59
[non_deductible_amount] => 0.00
[total_amount] => 296.00
[fee_amount] => 8.88
[net_amount] => 287.12
[trxn_id] => in_1FlKFWAwDzuDdbFCuWUlA4EZ
[invoice_id] => 0f3dd1eda0400becb9ecd33c58d28ae8
[invoice_number] =>
[currency] => USD
[cancel_date] =>
[cancel_reason] => 0
[receipt_date] => 2019-12-02 13:07:56
[thankyou_date] =>
[source] => Online Contribution: PowerBase Subscription Payment with Monthly Payment Option
[amount_level] =>
[contribution_recur_id] => 19
[is_test] => 0
[is_pay_later] => 0
[contribution_status_id] => 1
[address_id] => 24745
[check_number] =>
[campaign_id] =>
[creditnote_id] =>
[tax_amount] =>
[revenue_recognition_date] =>
[is_template] => 0
)
Array
(
[id] => 3951
[contact_id] => 10459
[financial_type_id] => 2
[contribution_page_id] => 14
[payment_instrument_id] => 1
[receive_date] => 2020-01-02 13:08:03
[non_deductible_amount] => 0.00
[total_amount] => 296.00
[fee_amount] => 8.88
[net_amount] => 287.12
[trxn_id] => in_1FwZ1bAwDzuDdbFCXoBfw8UM
[invoice_id] =>
[invoice_number] =>
[currency] => USD
[cancel_date] =>
[cancel_reason] =>
[receipt_date] => 2020-01-02 14:13:42
[thankyou_date] =>
[source] => Online Contribution: PowerBase Subscription Payment with Monthly Payment Option
[amount_level] =>
[contribution_recur_id] => 19
[is_test] => 0
[is_pay_later] => 0
[contribution_status_id] => 1
[address_id] =>
[check_number] =>
[campaign_id] =>
[creditnote_id] =>
[tax_amount] =>
[revenue_recognition_date] =>
[is_template] => 0
)
Array
(
[id] => 3999
[contact_id] => 10459
[financial_type_id] => 2
[contribution_page_id] => 14
[payment_instrument_id] => 1
[receive_date] => 2020-02-02 13:08:03
[non_deductible_amount] => 0.00
[total_amount] => 296.00
[fee_amount] => 8.88
[net_amount] => 287.12
[trxn_id] => in_1G7nnbAwDzuDdbFCvncHVNPH
[invoice_id] =>
[invoice_number] =>
[currency] => USD
[cancel_date] =>
[cancel_reason] =>
[receipt_date] => 2020-02-07 15:03:30
[thankyou_date] =>
[source] => Online Contribution: PowerBase Subscription Payment with Monthly Payment Option
[amount_level] =>
[contribution_recur_id] => 19
[is_test] => 0
[is_pay_later] => 0
[contribution_status_id] => 1
[address_id] =>
[check_number] =>
[campaign_id] =>
[creditnote_id] =>
[tax_amount] =>
[revenue_recognition_date] =>
[is_template] => 0
)
=== NOTE: count is one, but no results from first() ===
count is: 1
First...
www-data@fecbf38eb0bb:~/powerbase$
```https://lab.civicrm.org/dev/core/-/issues/1578API4: 500 error on chain with custom field2020-07-19T20:07:08ZJonGoldAPI4: 500 error on chain with custom fieldIn API Explorer, I created two API chained commands. When I chain using the contact ID, it works; with a contact reference custom field, it fails.
**Works**
```php
$contributions = \Civi\Api4\Contribution::get()
->addSelect('contact_...In API Explorer, I created two API chained commands. When I chain using the contact ID, it works; with a contact reference custom field, it fails.
**Works**
```php
$contributions = \Civi\Api4\Contribution::get()
->addSelect('contact_id')
->setChain([
'name_me_0' => ['Contact', 'get', ['where' => [['id', '=', '$contact_id']]], 0],
])
->execute();
foreach ($contributions as $contribution) {
// do something
}
```
**Fails**
```php
$contributions = \Civi\Api4\Contribution::get()
->setSelect([
'contact_id',
])
->addWhere('contact_id', '=', 127364)
->addWhere('contribution_status.value', '!=', 'Pending')
->addOrderBy('receive_date', 'ASC')
->setChain([
'name_me_1' => ['Contact', 'get', ['where' => [['id', '=', '$gift_details.Acknowledgee']]], 0],
])
->setCheckPermissions(FALSE)
->execute();
foreach ($contributions as $contribution) {
// do something
}
```
![Selection_803](/uploads/06edff3ad38a54a935f0d70cea93d5fe/Selection_803.png)https://lab.civicrm.org/dev/core/-/issues/1563API explorer fatal joining to contribution from contact2020-08-31T02:04:59ZeileenAPI explorer fatal joining to contribution from contact
```
$contacts = civicrm_api4('Contact', 'get', [
'where' => [
['contributions.id', '=', 5],
],
'limit' => 25,
]);
```
The above generated from the api explorer ![Screen_Shot_2020-01-30_at_6.12.52_PM](/uploads/dcb4d2bfa22fdc6...
```
$contacts = civicrm_api4('Contact', 'get', [
'where' => [
['contributions.id', '=', 5],
],
'limit' => 25,
]);
```
The above generated from the api explorer ![Screen_Shot_2020-01-30_at_6.12.52_PM](/uploads/dcb4d2bfa22fdc6d9e658d86600c03df/Screen_Shot_2020-01-30_at_6.12.52_PM.png)gives a fatal error
Annoyingly the debug doesn't work when there is a mysql syntax error but the bug is in the join
SELECT a.id as `id`, a.display_name as `display_name`, a.preferred_language as `preferred_language` FROM civicrm_contact a LEFT JOIN `civicrm_email` `emails` ON a.id = emails.contact_id LEFT JOIN `civicrm_contribution` `contributions` ON a.id = contributions.contribution_contact_id WHERE (`contributions`.`id` = "6940") AND (`emails`.`is_primary` = "") AND (`a`.`is_deleted` = "0") LIMIT 25 OFFSET 0 [nativecode=1054 ** Unknown column 'contributions.contribution_contact_id' in 'on clause']
@colemanw FYIhttps://lab.civicrm.org/dev/core/-/issues/1970API4 "where" doesn't fully work for checkbox/multi-select options2020-09-01T15:13:32ZnoahAPI4 "where" doesn't fully work for checkbox/multi-select optionsOverview
----------------------------------------
If I want to search for records which contain a particular option value (or values) in a multi-value custom field, there's currently no clean way to do that using APIv4's "get" action.
T...Overview
----------------------------------------
If I want to search for records which contain a particular option value (or values) in a multi-value custom field, there's currently no clean way to do that using APIv4's "get" action.
This limitation of API4's "where" clauses may also apply to "update" and "delete" actions, but I only investigated "get".
Reproduction steps
----------------------------------------
1. Create an option group with a couple options. Use that option group in creating a custom checkbox or multiple-select field on Contacts.
2. Create a contact who has two options selected in that custom field.
3. Try to use API v4 to "get" that contact, using one or both of the option values in that custom field in the "where" parameter.
You can [run through these reproduction steps using this code](https://lab.civicrm.org/dev/core/-/snippets/53).
Current behaviour
----------------------------------------
Records containing specific value options cannot be found successfully, except perhaps by hackily using "LIKE" with wildcards and Civi's VALUE_SEPARATOR character. In some cases when there is only a single value in the multi-value field, and you specify that option in the "where" parameter, the API will return the record, but looking at the generated SQL I think this is a fluke of collation or something.
Expected behaviour
----------------------------------------
When you use the "=" operator and a single option value in the "where" parameter, the API should return records that have exactly (and only) that one option selected.
Beyond that, we need to decide how it should work. I should be able to search for records where options A and C are selected, but not B. There might need to be a pair of custom operators, "contains" and "doesn't contain", for this purpose. These would translate into SQL LIKE or RLIKE comparisons using the VALUE_SEPARATOR. Note that there are currently some issues with RLIKE in Advanced Search as I note in #1967.https://lab.civicrm.org/dev/core/-/issues/1428APIv4 Activity::update() causes target contacts and assignees to be deleted2020-10-09T20:47:08ZPatrick Figelpfigel@greenpeace.orgAPIv4 Activity::update() causes target contacts and assignees to be deletedOverview
----------------------------------------
In APIv4, `\Civi\Api4\Activity::update()` causes target contacts and assignees to be deleted from `ActivityContact`.
Reproduction steps (includes links to APIv4 Explorer on dmaster)
----...Overview
----------------------------------------
In APIv4, `\Civi\Api4\Activity::update()` causes target contacts and assignees to be deleted from `ActivityContact`.
Reproduction steps (includes links to APIv4 Explorer on dmaster)
----------------------------------------
1. [Create a new activity and assign it to a target contact](https://dmaster.demo.civicrm.org/civicrm/api4#/explorer/Activity/create?values=%5B%5B%22subject%22,%22foo321%22%5D,%5B%22activity_type_id%22,%221%22%5D,%5B%22source_contact_id%22,%2270%22%5D%5D&chain=%5B%5B%22name_me_0%22,%5B%22ActivityContact%22,%22create%22,%22%7Bvalues:%20%7Bactivity_id:%20$id,%20contact_id:%2010,%20record_type_id:%203%7D%7D%22,%220%22%5D%5D%5D)
2. [Observe that the activity has a target contact](https://dmaster.demo.civicrm.org/civicrm/api4#/explorer/ActivityContact/get?where=%5B%5B%22activity.subject%22,%22%3D%22,%22foo321%22%5D%5D)
3. [Update an unrelated activity field using `\Civi\Api4\Activity::update()`](https://dmaster.demo.civicrm.org/civicrm/api4#/explorer/Activity/update?where=%5B%5B%22subject%22,%22%3D%22,%22foo321%22%5D%5D&values=%5B%5B%22duration%22,%222%22%5D%5D)
4. [Observe that the target contact was deleted](https://dmaster.demo.civicrm.org/civicrm/api4#/explorer/ActivityContact/get?where=%5B%5B%22activity.subject%22,%22%3D%22,%22foo321%22%5D%5D)
Current behaviour
----------------------------------------
Target contact and assignees are deleted from `ActivityContact`. Source contact is preserved.
Expected behaviour
----------------------------------------
Target contacts and assignees should be preserved.
Environment information
----------------------------------------
<!-- Some of the items below may not be relevant for every bug - if in doubt please include more information than you think is neccessary. -->
* __CiviCRM:__ _Master_
* __PHP:__ _7.2_
Comments
----------------------------------------
Not sure if this ever worked, we have no existing code that calls this.https://lab.civicrm.org/dev/core/-/issues/2271Free the joins! APIv4 explicit joins - can we remove the requirement for spec...2021-01-04T14:23:01ZnoahFree the joins! APIv4 explicit joins - can we remove the requirement for specific columns in the "on" clause?API4 currently micromanages the join conditions of explicit joins, forcing us to use awkward workarounds if we want to join entities on arbitrary conditions.
For example, I'd like to be able to join Email to Email so I can find differen...API4 currently micromanages the join conditions of explicit joins, forcing us to use awkward workarounds if we want to join entities on arbitrary conditions.
For example, I'd like to be able to join Email to Email so I can find different contacts who have the same email addresses. The Email's id is irrelevant to the join; what's relevant are the "email" and "contact_id" fields. See https://civicrm.stackexchange.com/a/38496/446.
Currently, APIv4 enforces a requirement that explicit joins have an "id" column for the joined entity in one of the join's "on" conditions. This enforcement takes place in Api4SelectQuery::getJoinConditions(). If no "on" condition with a "joinEntity.id" column is explicitly given, the code tries to create a new "on" condition using a foreign key relationship from the entity's metadata.
I can trick APIv4 into doing what I want by specifying a gratuitous "on" condition of the form "joinEntity.id = joinEntity.id". See the SE link above for an example. But this smells bad to me. When it comes to explicit join conditions, can't we figure out a way to tell APIv4 "step back, I'll handle this"?https://lab.civicrm.org/dev/core/-/issues/2360SearchKit : use of rows in query cause mysql errors2021-02-22T22:07:08ZsamuelsovSearchKit : use of rows in query cause mysql errorsWhen doing a Group by in the query, and displaying the results with a pager, I get this error :
```
$Fatal Error Details = Array
(
[callback] => Array
(
[0] => CRM_Core_Error
[1] => exceptionHandler
...When doing a Group by in the query, and displaying the results with a pager, I get this error :
```
$Fatal Error Details = Array
(
[callback] => Array
(
[0] => CRM_Core_Error
[1] => exceptionHandler
)
[code] => -2
[message] => DB Error: syntax error
[mode] => 16
[debug_info] => SELECT count(*) AS `c` FROM ( SELECT `a`.`id` AS `id`
FROM civicrm_contact a
WHERE (`a`.`is_deleted` = "0")
HAVING (`id` IS NOT NULL)
) AS rows [nativecode=1064 ** You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'rows' at line 5]
[type] => DB_Error
[user_info] => SELECT count(*) AS `c` FROM ( SELECT `a`.`id` AS `id`
FROM civicrm_contact a
WHERE (`a`.`is_deleted` = "0")
HAVING (`id` IS NOT NULL)
) AS rows [nativecode=1064 ** You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'rows' at line 5]
[to_string] => [db_error: message="DB Error: syntax error" code=-2 mode=callback callback=CRM_Core_Error::exceptionHandler prefix="" info="SELECT count(*) AS `c` FROM ( SELECT `a`.`id` AS `id`
FROM civicrm_contact a
WHERE (`a`.`is_deleted` = "0")
HAVING (`id` IS NOT NULL)
) AS rows [nativecode=1064 ** You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'rows' at line 5]"]
)
```https://lab.civicrm.org/dev/core/-/issues/2444Searchkit search display links - can we offer option to open in an popup2021-03-18T01:59:42ZeileenSearchkit search display links - can we offer option to open in an popupWhen configuring links for search display it would be nice to be able to specify if they should open as a pop up/ modal (currently they open in a new screen and there is no choice to do differently)When configuring links for search display it would be nice to be able to specify if they should open as a pop up/ modal (currently they open in a new screen and there is no choice to do differently)https://lab.civicrm.org/dev/core/-/issues/2488api3 api4 OptionValue.create and OptionValue.update: Setting the default valu...2021-04-06T21:27:14Zmartin.wapi3 api4 OptionValue.create and OptionValue.update: Setting the default value (is_default=1) ignores domain IDOverview
----------------------------------------
It seems that when you call either `OptionValue.create` or `OptionValue.update` using either `api3` or `api4` and you set "is default" to "true" (`is_default = 1`), this ignores the `civi...Overview
----------------------------------------
It seems that when you call either `OptionValue.create` or `OptionValue.update` using either `api3` or `api4` and you set "is default" to "true" (`is_default = 1`), this ignores the `civicrm_option_value.domain_id` column even when multisite is enabled. It sets the `is_default` field value to `1` for the new or updated record, but forces `is_default` to `0` (zero) for all other records in the Option Group, regardless of `domain_id`.
I noticed this because I was trying to script a multisite deployment on WordPress using the `wp cv` and `cv.phar` CLI tools. CiviCRM wants each site (domain ID) in the multisite to have its own default "From Email Address" (DB `option_group_name = "from_email_address"`), and it complains via an alert message if that is not configured. The Civi admin UI allows you to set a separate default "From Email Address" for each domain ID. (SQL query shows multiple records with "civicrm_option_value.is_default = 1", one per domain ID.) But when you invoke `OptionValue.create` or `OptionValue.update` specifying `is_default = 1`, then the "last update wins." Only the last added or updated record will have `is_default = 1`.
Reproduction steps
----------------------------------------
1. Set up a multi-domain Civi installation with, say, three different sites. (I created mine on WordPress.)
1. Via the UI, navigate to the Civi dashboard for each site. You should see the prompt to set a default "From Email Address".
1. Using the UI, add a default email address for each site.
1. Inspect the `civicrm_option_value` table with a query like the following to verify there are multiple default values (one per domain ID). Also take note if the `civicrm_option_value.id` values for use in the subsequent API calls below.
```
select y.id, y.name, y.is_default, y.domain_id, y.label, y.option_group_id, x.name as option_group_name
from civicrm_option_value y
inner join civicrm_option_group x on x.id = y.option_group_id
where x.name='from_email_address'
```
5. At the command prompt, try any combination of or variations of the following API calls to add or update an option value record as the default.
6. After each of the API calls, re-inspect the `civicrm_option_value` table to verify that there is now only one `civicrm_option_value` record with `is_default = 1` for the Option Group 'from_email_address' corresponding to the most recent add/update, regardless of domain ID.
```
STDEMAIL="webmaster@a_great_nonprofit.org"
DOMAIN1=site1.agreatnonprofit.org
DOMAINID1=1
DOMAIN2=site2.agreatnonprofit.org
DOMAINID2=20
DOMAIN3=site3.agreatnonprofit.org
DOMAINID3=30
wp cv api OptionValue.create option_group_id=from_email_address label="$STDEMAIL" name="$STDEMAIL" is_default=1 --url=$DOMAIN1
wp cv api OptionValue.create option_group_id=from_email_address label="$STDEMAIL" name="$STDEMAIL" is_default=1 --url=$DOMAIN2
wp cv api OptionValue.create option_group_id=from_email_address label="$STDEMAIL" name="$STDEMAIL" is_default=1 domain_id=$DOMAINID3 --url=$DOMAIN3
wp cv api OptionValue.get sequential=1 limit=1 option_group_id="from_email_address" options='{"sort":"is_default DESC"}' domain_id=$DOMAINID1 --url=$DOMAIN1
# Using the output from the above, get the record ID from the civicrm_option_value table (RECORDID)
RECORDID1={record_id_from_above}
export SITEURL="$DOMAIN1"
cv api4 OptionValue.update +w "id = $RECORDID1" +w "domain_id = $DOMAINID1" +v is_default=true +v "label=\"$STDEMAIL\"" +v "name=\"$STDEMAIL\""
# for simplicity here assume that for DOMAIN2, the civicrm_option_value.id = 1020
export SITEURL="$DOMAIN2"
cv api4 OptionValue.update '{"where":[["id","=",1020],["domain_id","=",20]],"values":{"is_default":true,"label":"webmaster@a_great_nonprofit.org","name":"webmaster@a_great_nonprofit.org"}}'
```
Current behavior
----------------------------------------
Any `OptionValue.create` or `OptionValue.update` API call with either `api3` or `api4` that has `is_default = 1` will set `is_default = 1` for the target DB record, but will force all other `civicrm_option_value` records with the same `option_group_id` to `is_default = 0` **regardless of the domain ID**.
Expected behavior
----------------------------------------
`OptionValue.create` or `OptionValue.update` should:
1. Enforce one `is_default = 1` default record for each `option_group_id, domain_id` tuple.
1. Or: if some Option Groups should always ignore the domain ID, then the API should be smart enough to know which option group names (like 'from_email_address') should allow a default record for each domain ID and which ones should not.
1. Or: it should respect the domain ID when CiviCRM multisite is "enabled" and ignore it otherwise. However, in this last case, it seems that there should be only one domain ID `1`, so this perhaps reduces to #1 above.
Environment information
----------------------------------------
* __Browser:__ 89.0.4389.90
* __CiviCRM:__ 5.35.1
* __PHP:__ 7.2
* __CMS:__ WordPress 5.4.4
* __Database:__ MariaDB 10.3
* __Web Server:__ Apache 2.4
For command-line use of `cv` my `civicrm.settings.php` file inspects the `SITEURL` environment variable and sets the correct Civi domain ID, domain group ID, and domain organization ID.
Comments
----------------------------------------
It seems I keep crashing on the dangerous shoals of CiviCRM multisite/multi-domain! ;-) It would be helpful to have an up-to-date summary of the limitations, known issues, and potential gotchas of working with multisite.https://lab.civicrm.org/dev/core/-/issues/2573api4: CaseActivity requires "administer CiviCRM" permission2021-04-29T03:37:13ZDaveDapi4: CaseActivity requires "administer CiviCRM" permissionI think the easiest way to see this is:
1. Add a user that has view all contacts, edit all contacts, view all activities, "all" the case permissions, add contacts, access CiviCRM, etc just don't give it administer CiviCRM.
1. Create a c...I think the easiest way to see this is:
1. Add a user that has view all contacts, edit all contacts, view all activities, "all" the case permissions, add contacts, access CiviCRM, etc just don't give it administer CiviCRM.
1. Create a case, doesn't matter which user creates it.
1. Note the activity id of any of the activities on the case.
1. Replace 1234 in this command with the id:
* `cv ev --user=the_user "$r = \Civi\Api4\Activity::get(TRUE)->addSelect('id', 'case_activity.case_id')->setJoin([['CaseActivity AS case_activity', 'LEFT']])->addWhere('id', '=', 1234)->execute()->first(); var_dump($r);"`
1. Note the case id is not returned.
1. Now run the same thing but replace with --user=admin, where admin has administer CiviCRM.
1. The case id is returned.
It was suggested in chat that the class maybe needs a permission override somewhere.
A similar thing happens if I use a chain instead of join.
I don't think this strictly counts as a regression since CaseActivity was just added recently.5.37.0https://lab.civicrm.org/dev/core/-/issues/2592Afform: Replace Actions on Join not available for anon users2021-05-18T15:46:03ZseamusleeAfform: Replace Actions on Join not available for anon usersWhilst testing the work on Entity Reference fields in PR https://github.com/civicrm/civicrm-core/pull/20216 I found that when I constructed a form with the attached JSON and the attached markup I would get these errors if I filled in eit...Whilst testing the work on Entity Reference fields in PR https://github.com/civicrm/civicrm-core/pull/20216 I found that when I constructed a form with the attached JSON and the attached markup I would get these errors if I filled in either the Email field or the Website field for the relevant parts
```
Array
(
[error_id] => ihJT-pVbh-Papi
[exception] => Civi\API\Exception\UnauthorizedException: "Cannot process APIv4 request for Individual1 (Email.replace): Action is not approved"
#0 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php(89): Civi\Afform\FormDataModel->Civi\Afform\{closure}("Email", "replace", (Array:3))
#1 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php(57): Civi\Api4\Action\Afform\Submit::saveJoins(Object(Closure), "Contact", "207", (Array:1))
#2 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/vendor/symfony/event-dispatcher/EventDispatcher.php(214): Civi\Api4\Action\Afform\Submit::processContacts(Object(Civi\Afform\Event\AfformSubmitEvent), "civi.afform.submit", Object(Civi\Core\CiviEventDispatcher))
#3 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/vendor/symfony/event-dispatcher/EventDispatcher.php(44): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch((Array:2), "civi.afform.submit", Object(Civi\Afform\Event\AfformSubmitEvent))
#4 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/Civi/Core/CiviEventDispatcher.php(129): Symfony\Component\EventDispatcher\EventDispatcher->dispatch("civi.afform.submit", Object(Civi\Afform\Event\AfformSubmitEvent))
#5 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php(36): Civi\Core\CiviEventDispatcher->dispatch("civi.afform.submit", Object(Civi\Afform\Event\AfformSubmitEvent))
#6 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php(44): Civi\Api4\Action\Afform\Submit->processForm()
#7 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/Civi/Api4/Provider/ActionObjectProvider.php(68): Civi\Api4\Action\Afform\AbstractProcessor->_run(Object(Civi\Api4\Generic\Result))
#8 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/Civi/API/Kernel.php(149): Civi\Api4\Provider\ActionObjectProvider->invoke(Object(Civi\Api4\Action\Afform\Submit))
#9 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/Civi/Api4/Generic/AbstractAction.php(239): Civi\API\Kernel->runRequest(Object(Civi\Api4\Action\Afform\Submit))
#10 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/api/api.php(85): Civi\Api4\Generic\AbstractAction->execute()
#11 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Api4/Page/AJAX.php(139): civicrm_api4("Afform", "submit", (Array:4), NULL)
#12 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Api4/Page/AJAX.php(80): CRM_Api4_Page_AJAX->execute("Afform", "submit", (Array:4), NULL)
#13 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Core/Invoke.php(313): CRM_Api4_Page_AJAX->run((Array:5), NULL)
#14 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Core/Invoke.php(69): CRM_Core_Invoke::runItem((Array:12))
#15 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Core/Invoke.php(36): CRM_Core_Invoke::_invoke((Array:5))
#16 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/drupal/civicrm.module(458): CRM_Core_Invoke::invoke((Array:5))
#17 /home/seamus/buildkit/build/47-test/web/includes/menu.inc(527): civicrm_invoke("ajax", "api4", "Afform", "submit")
#18 /home/seamus/buildkit/build/47-test/web/index.php(21): menu_execute_active_handler()
#19 {main}
)
May 06 17:31:21 [debug] AJAX Error ({error_id}): failed with exception
Array
(
[error_id] => g6Pr-4qZq-aCoC
[exception] => Civi\API\Exception\UnauthorizedException: "Cannot process APIv4 request for Organization1 (Website.replace): Action is not approved"
#0 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php(89): Civi\Afform\FormDataModel->Civi\Afform\{closure}("Website", "replace", (Array:3))
#1 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php(57): Civi\Api4\Action\Afform\Submit::saveJoins(Object(Closure), "Contact", "209", (Array:1))
#2 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/vendor/symfony/event-dispatcher/EventDispatcher.php(214): Civi\Api4\Action\Afform\Submit::processContacts(Object(Civi\Afform\Event\AfformSubmitEvent), "civi.afform.submit", Object(Civi\Core\CiviEventDispatcher))
#3 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/vendor/symfony/event-dispatcher/EventDispatcher.php(44): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch((Array:2), "civi.afform.submit", Object(Civi\Afform\Event\AfformSubmitEvent))
#4 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/Civi/Core/CiviEventDispatcher.php(129): Symfony\Component\EventDispatcher\EventDispatcher->dispatch("civi.afform.submit", Object(Civi\Afform\Event\AfformSubmitEvent))
#5 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/ext/afform/core/Civi/Api4/Action/Afform/Submit.php(36): Civi\Core\CiviEventDispatcher->dispatch("civi.afform.submit", Object(Civi\Afform\Event\AfformSubmitEvent))
#6 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php(44): Civi\Api4\Action\Afform\Submit->processForm()
#7 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/Civi/Api4/Provider/ActionObjectProvider.php(68): Civi\Api4\Action\Afform\AbstractProcessor->_run(Object(Civi\Api4\Generic\Result))
#8 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/Civi/API/Kernel.php(149): Civi\Api4\Provider\ActionObjectProvider->invoke(Object(Civi\Api4\Action\Afform\Submit))
#9 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/Civi/Api4/Generic/AbstractAction.php(239): Civi\API\Kernel->runRequest(Object(Civi\Api4\Action\Afform\Submit))
#10 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/api/api.php(85): Civi\Api4\Generic\AbstractAction->execute()
#11 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Api4/Page/AJAX.php(139): civicrm_api4("Afform", "submit", (Array:4), NULL)
#12 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Api4/Page/AJAX.php(80): CRM_Api4_Page_AJAX->execute("Afform", "submit", (Array:4), NULL)
#13 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Core/Invoke.php(313): CRM_Api4_Page_AJAX->run((Array:5), NULL)
#14 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Core/Invoke.php(69): CRM_Core_Invoke::runItem((Array:12))
#15 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/CRM/Core/Invoke.php(36): CRM_Core_Invoke::_invoke((Array:5))
#16 /home/seamus/buildkit/build/47-test/web/sites/all/modules/civicrm/drupal/civicrm.module(458): CRM_Core_Invoke::invoke((Array:5))
#17 /home/seamus/buildkit/build/47-test/web/includes/menu.inc(527): civicrm_invoke("ajax", "api4", "Afform", "submit")
#18 /home/seamus/buildkit/build/47-test/web/index.php(21): menu_execute_active_handler()
#19 {main}
```
thoughts @colemanw @totten
[afformRegisterASite.aff.html](/uploads/da267f8d0ec569d9081f211eeb86c6ae/afformRegisterASite.aff.html)
[afformRegisterASite.aff.json](/uploads/de9c7e89d13e2d2216256e2a63a145fd/afformRegisterASite.aff.json)colemanwcolemanwhttps://lab.civicrm.org/dev/core/-/issues/2622APiv4 does not handled display name when only email is provided2021-05-27T22:27:30ZeileenAPiv4 does not handled display name when only email is providedDemonstrated in the test https://github.com/civicrm/civicrm-core/pull/18865
Options are
1) accept that it's OK to pass 'email' to contact.create bao even though it is not a 'contact field' or
2) do an extra check on every primary email...Demonstrated in the test https://github.com/civicrm/civicrm-core/pull/18865
Options are
1) accept that it's OK to pass 'email' to contact.create bao even though it is not a 'contact field' or
2) do an extra check on every primary email save - note that historically parsing the smarty greeting tpl for the display name is expensive so we'd need to only set if empty.
I'm on the fence about the performance of 2 - most of our db locks these days are actually db insert locks on the email table for some reason (now that we have eliminated the acl related locks)
@colemanw - but to gitlab as promisedhttps://lab.civicrm.org/dev/core/-/issues/2621APIv4, setCheckPermissions FALSE is required to get listing of Events for Ano...2021-06-07T03:17:08Zjustinfreeman (Agileware)APIv4, setCheckPermissions FALSE is required to get listing of Events for Anonymous usersAPIv4, setCheckPermissions FALSE is required to get listing of Events for Anonymous users, despite Anonymous having access to Events. The same type of call using APIv3 works without error.
Tested using a standard CiviCRM 5.37.2 install ...APIv4, setCheckPermissions FALSE is required to get listing of Events for Anonymous users, despite Anonymous having access to Events. The same type of call using APIv3 works without error.
Tested using a standard CiviCRM 5.37.2 install on WordPress. The same site allows Anonymous access to the CiviCRM event listing page, /civicrm/event/list/?reset=1
Here's example code which will return a **403 unauthorised error** for anonymous users.
```
$results = \Civi\Api4\Event::get()
->addSelect('id', 'title', 'start_date', 'end_date', 'event_tz', 'event_type_id', 'is_online_registration')
->addWhere('start_date', '>=', 'today')
->addWhere('is_public', '=', TRUE)
->addWhere('is_active', '=', TRUE)
->addOrderBy('start_date', 'ASC');
```
However, this code will work for anonymous users.
```
$results = \Civi\Api4\Event::get()
->addSelect('id', 'title', 'start_date', 'end_date', 'event_tz', 'event_type_id', 'is_online_registration')
->addWhere('start_date', '>=', 'today')
->addWhere('is_public', '=', TRUE)
->addWhere('is_active', '=', TRUE)
->addOrderBy('start_date', 'ASC')
->setCheckPermissions(FALSE);
```
**It's not clear why setCheckPermissions would be required at all for this type of API call.**
Agileware Ref: CIVICRM-1764https://lab.civicrm.org/dev/core/-/issues/2699Failing api4 test api.v4.Action.CreateWithOptionGroupTest.testWithCustomDataF...2021-07-21T20:07:07ZDaveDFailing api4 test api.v4.Action.CreateWithOptionGroupTest.testWithCustomDataForMultipleContactsSo the BAO CustomField looks maybe buggy to me. At [this line](https://github.com/civicrm/civicrm-core/blob/d5cb55868ef0f1f173f678780e4cba7b53552891/CRM/Core/BAO/CustomField.php#L2016-L2017), it says for almost any type except text, let'...So the BAO CustomField looks maybe buggy to me. At [this line](https://github.com/civicrm/civicrm-core/blob/d5cb55868ef0f1f173f678780e4cba7b53552891/CRM/Core/BAO/CustomField.php#L2016-L2017), it says for almost any type except text, let's see about creating an option group. And then it says, partly, if it's a new field and there's no option_group_id specified, let's create a dummy one for it with `name` based on timestamp. Unless you've passed in the magic number 2.
Since in unit tests the timestamp is almost constant, you get a duplicate sometimes if the second hasn't rolled over yet.
Or, the tests should clean up the dummy option groups too.
FYI @colemanw @eileen @seamuslee5.40.0https://lab.civicrm.org/dev/core/-/issues/2771Api join changes break rather than deprecate2021-08-21T05:30:05ZeileenApi join changes break rather than deprecateWe have had some interntional changes in preferred syntax & deprecation - but no expecation of any changes to apiv4 that are not backward compatible.
However, this api call that works on 5.39 fails on 5.41
```
// Check for existing......We have had some interntional changes in preferred syntax & deprecation - but no expecation of any changes to apiv4 that are not backward compatible.
However, this api call that works on 5.39 fails on 5.41
```
// Check for existing....
$matches = Email::get(FALSE)
->addWhere('contact.first_name', '=', $msg['first_name'])
->addWhere('contact.last_name', '=', $msg['last_name'])
->addWhere('contact.is_deleted', '=', 0)
->addWhere('contact.is_deceased', '=', 0)
->addWhere('email', '=', $msg['email'])
->addWhere('is_primary', '=', TRUE)
->setSelect(['contact_id'])
->setLimit(2)
->execute();
if (count($matches) === 1) {
return $matches->first()['contact_id'];
}
```
```
14:05:39 API_Exception: Invalid field 'contact.first_name'
14:05:39
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Query/Api4SelectQuery.php:636
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Query/Api4SelectQuery.php:440
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Query/Api4SelectQuery.php:411
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Query/Api4SelectQuery.php:284
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Query/Api4SelectQuery.php:136
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Query/Api4SelectQuery.php:151
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Generic/DAOGetAction.php:111
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Generic/DAOGetAction.php:99
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Provider/ActionObjectProvider.php:68
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/API/Kernel.php:149
14:05:39 /src/wikimedia/fundraising/crm/civicrm/Civi/Api4/Generic/AbstractAction.php:207
```5.41.0https://lab.civicrm.org/dev/core/-/issues/2634Membership api for v42021-08-25T22:27:29ZeileenMembership api for v4Apiv4 doesn't have a membership api yet - mostly because of issues with the membership.create process.
I caught up with @kcristiano this week & we fleshed out what the 3 issues are
1) Membership api does financial stuff including creat...Apiv4 doesn't have a membership api yet - mostly because of issues with the membership.create process.
I caught up with @kcristiano this week & we fleshed out what the 3 issues are
1) Membership api does financial stuff including creating line items and in some cases creating contribution. I worked through getting rid of one of these bits of magic, converting the back office form to use Order api when setting up a new recurring membership. Getting review on this was slow going so it will take a long time to convert other places. (I have started on the batch membership form & Kevin is going to help with review there).
However, I made a proposal that Kevin agreed with that we simply don't touch ANY of that financial stuff if $params['version'] === 4. The idea is that the handling (which may or may not be right) for apiv3 and for those calls that still call the BAO directly will be unchanged but for v4 callers need to either
a) call the order api (which we will fix to call the v4 membership api internally) or
b) create their own line items. Note that memberships without contributions actually should have line items according to the model.
I will work on this once we have fixed some issues with the order api's integrity - https://github.com/civicrm/civicrm-core/pull/20656 is the most obvious but the intent is to get the extra cover that deprecating our random magic will provide https://github.com/civicrm/civicrm-core/pull/20678 too. (This is not a big piece of work but it requires fairly experienced review )
2) Membership date handling for new memberships is in the v3 api (and the form layer). I did a patch for this. https://github.com/civicrm/civicrm-core/pull/20759 -
3) Membership date handling for renewals. Apiv3 has some magic around this that is not in the BAO. I have come to the conclusion we can handle this by
-- using the Order->payment flow. In other words the dates are calculated at the point when Payment.create is added, using the membership_num_terms as stored in https://github.com/civicrm/civicrm-core/pull/20672
-- OR - if that flow won't work for people for any reason, they can pass in all the date values.5.42.0https://lab.civicrm.org/dev/core/-/issues/2768APiv4 - where did getLanguage go?2021-08-26T02:06:48ZeileenAPiv4 - where did getLanguage go?I have an api that works on 5.39 but fails on 5.41 which was using `setLanguage` and `getLanguage` by inheritance
```
*
* @package Civi\Api4
*/
class Save extends \Civi\Api4\Generic\AbstractAction {
```
I will probably re-write the ...I have an api that works on 5.39 but fails on 5.41 which was using `setLanguage` and `getLanguage` by inheritance
```
*
* @package Civi\Api4
*/
class Save extends \Civi\Api4\Generic\AbstractAction {
```
I will probably re-write the code making this call & perhaps no-one else will hit it - but I'm a bit mystified at the disappearance5.41.0https://lab.civicrm.org/dev/core/-/issues/2682APIv4 - entityBatch linkage2021-08-30T02:21:22ZeileenAPIv4 - entityBatch linkageThis comes from discussion here https://github.com/civicrm/civicrm-core/pull/20505
The issue is that to make it usable in search kit we need a pseudoconstant for what is allowed for 'entity_table'
In core I think this is ONLY civicrm_f...This comes from discussion here https://github.com/civicrm/civicrm-core/pull/20505
The issue is that to make it usable in search kit we need a pseudoconstant for what is allowed for 'entity_table'
In core I think this is ONLY civicrm_financial_trxn. However, gift-aid also added civicrm_contribution
My best idea at the moment is to use an option group (and create a PR against giftaid to add it + use release notes & dev-digest)https://lab.civicrm.org/dev/core/-/issues/2984APIv4: Confusing error when calling CaseType API2021-12-09T21:08:05ZtottenAPIv4: Confusing error when calling CaseType APIOverview
----------------------------------------
`CaseType.get` API has a confusing disposition.
Reproduction steps
----------------------------------------
1. Disable CiviCase
1. Call `cv api4 CaseType.get`
Current behavior
--------...Overview
----------------------------------------
`CaseType.get` API has a confusing disposition.
Reproduction steps
----------------------------------------
1. Disable CiviCase
1. Call `cv api4 CaseType.get`
Current behavior
----------------------------------------
The call to `CaseType.get` begins executing - but it fails in the middle of query-building.
```
cv api4 CaseType.get -v
Entity: CaseType
Action: get
Params: {
"version": 4,
"checkPermissions": false
}
[Symfony\Component\Debug\Exception\FatalThrowableError]
Type error: array_merge(): Argument #1 must be of type array, null given
Exception trace:
() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/Api4/Query/Api4SelectQuery.php:223
array_merge() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/Api4/Query/Api4SelectQuery.php:223
Civi\Api4\Query\Api4SelectQuery->buildSelectClause() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/Api4/Query/Api4SelectQuery.php:149
Civi\Api4\Query\Api4SelectQuery->getSql() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/Api4/Query/Api4SelectQuery.php:165
Civi\Api4\Query\Api4SelectQuery->run() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/Api4/Generic/DAOGetAction.php:111
Civi\Api4\Generic\DAOGetAction->getObjects() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/Api4/Generic/DAOGetAction.php:99
Civi\Api4\Generic\DAOGetAction->_run() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/Api4/Provider/ActionObjectProvider.php:68
Civi\Api4\Provider\ActionObjectProvider->invoke() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/API/Kernel.php:149
Civi\API\Kernel->runRequest() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/Civi/Api4/Generic/AbstractAction.php:234
Civi\Api4\Generic\AbstractAction->execute() at /home/m/bknix/build/tmp/web/sites/all/modules/civicrm/api/api.php:85
civicrm_api4() at phar:///home/m/bknix/bin/cv/src/Command/Api4Command.php:145
Civi\Cv\Command\Api4Command->execute() at phar:///home/m/bknix/bin/cv/vendor/symfony/console/Command/Command.php:257
Symfony\Component\Console\Command\Command->run() at phar:///home/m/bknix/bin/cv/vendor/symfony/console/Application.php:850
Symfony\Component\Console\Application->doRunCommand() at phar:///home/m/bknix/bin/cv/vendor/symfony/console/Application.php:193
Symfony\Component\Console\Application->doRun() at phar:///home/m/bknix/bin/cv/src/Application.php:46
Civi\Cv\Application->doRun() at phar:///home/m/bknix/bin/cv/vendor/symfony/console/Application.php:124
Symfony\Component\Console\Application->run() at phar:///home/m/bknix/bin/cv/src/Application.php:15
Civi\Cv\Application::main() at phar:///home/m/bknix/bin/cv/bin/cv:27
require() at /home/m/bknix/bin/cv:14
```
Expected behavior
----------------------------------------
Either:
* Allow `CaseType` API calls to work. Return the list of case types.
* OR... Disallow `CaseType` API calls. Give a clear error; eg
* `CaseType.get API is unavailable.`
* `Cannot process request. CiviCase is disabled.`https://lab.civicrm.org/dev/core/-/issues/2527SearchKit, Feature Request - provide ability to export/import saved Search us...2021-12-17T18:35:38Zjustinfreeman (Agileware)SearchKit, Feature Request - provide ability to export/import saved Search using JSON format to make it easier to share search definititionsSearchKit, Feature Request - provide ability to export/import saved Search using JSON format. This would make it easier to share search definititions between sites, replicate and modify manually, create a library of saved searches which ...SearchKit, Feature Request - provide ability to export/import saved Search using JSON format. This would make it easier to share search definititions between sites, replicate and modify manually, create a library of saved searches which can be distributed etc.