CiviCRM Core issueshttps://lab.civicrm.org/dev/core/-/issues2022-04-22T15:53:45Zhttps://lab.civicrm.org/dev/core/-/issues/3284APIv4 Query Improvements2022-04-22T15:53:45Zjoshjosh@civicrm.orgAPIv4 Query ImprovementsThis project will expand the query language of APIv4 to increase functionality. Implementing this will enhance the capabilities of APIv4-based Smart Groups; without this their utility will be limited to simple queries. This is also a pre...This project will expand the query language of APIv4 to increase functionality. Implementing this will enhance the capabilities of APIv4-based Smart Groups; without this their utility will be limited to simple queries. This is also a prerequisite to the Search Builder UI project.
Tasks:
- Implement Having, Group By parameters.
- Enable use of SQL Functions like SUM().
- Implement explicit joins.
- Implement a way to add subquery expressions to an API call.
Related pull-requests:
* [#16947 - Support GROUP BY and aggregate functions](https://github.com/civicrm/civicrm-core/pull/16947) (merged)
* [#17047 - Api4 Explorer: Support SQL functions and HAVING clause ](https://github.com/civicrm/civicrm-core/pull/17047) (merged)colemanwcolemanw2020-06-30https://lab.civicrm.org/dev/core/-/issues/3243Search Builder UI2022-04-22T15:52:31Zjoshjosh@civicrm.orgSearch Builder UIThis project will create a unified interface that replaces the current Advanced Search and Search Builder forms. This requires the APIv4 Query Improvements project to be done (or at least underway). This is a prerequisite to the Form-Bui...This project will create a unified interface that replaces the current Advanced Search and Search Builder forms. This requires the APIv4 Query Improvements project to be done (or at least underway). This is a prerequisite to the Form-Builder-based reports and custom searches projects.
The mockup for this interface is available at the bottom of https://lab.civicrm.org/dev/report/-/wikis/Search-Builder-Overhaul
Tasks:
- Selection of base table + joins
- Drag-n-drop nested and/or where clauses supporting all fields and operators
- Controls for grouping and sorting
- Display and paging of search results
- Configurable output columns with drag-n-droppable table headers
- Selection of actions to act upon output rows (e.g. “Add Tags”)
- Button to save query as APIv4-based smart group.colemanwcolemanw2020-06-30https://lab.civicrm.org/dev/core/-/issues/3242APIv4-Based Smart(er) Groups2022-04-22T15:52:29Zjoshjosh@civicrm.orgAPIv4-Based Smart(er) GroupsThis project will allow smart groups to be built from APIv4 criteria. The MVP would include a button in the API Explorer to save an api4 query as a smart group. This will also connect with the new Search Builder UI when that project is c...This project will allow smart groups to be built from APIv4 criteria. The MVP would include a button in the API Explorer to save an api4 query as a smart group. This will also connect with the new Search Builder UI when that project is complete.
Tasks:
- Allow swappable backend to smart groups
- Extend smart group schema to store api4 query parameters
- Add support for saving smart groups to API explorer UI.colemanwcolemanw2020-06-30https://lab.civicrm.org/dev/core/-/issues/1775civicrm_financial_trxn.fee_amount reversals mixed up2023-03-22T05:03:26ZJoeMurraycivicrm_financial_trxn.fee_amount reversals mixed upOverview
----------------------------------------
When doing reversal bookkeeping entry as part of changing a financial type, the fee_amount field does not have its sign reversed. This results in an incorrect net_amount field. See bug 1 ...Overview
----------------------------------------
When doing reversal bookkeeping entry as part of changing a financial type, the fee_amount field does not have its sign reversed. This results in an incorrect net_amount field. See bug 1 in https://gist.github.com/JoeMurray/6db6a82ff6c9e593ca5301b5f8708f52
Current behaviour
----------------------------------------
civicrm_financial_trxn.fee_amount has same value as original record in the reversal record. This results in net_amount not being a correct reversal of the original record's net_amount.
Expected behaviour
----------------------------------------
civicrm_financial_trxn.fee_amount has negative of value in original record in the reversal record. This results in net_amount being the negative in the reversal record of that field in the original record.
Comments
----------------------------------------
We should check for this issue wherever the code creates reversal transactions.
Make unit tests for all of the areas in the code where this occurs.seamusleeseamuslee2020-05-26https://lab.civicrm.org/dev/core/-/issues/2020Revert 20202022-10-11T14:54:01ZeileenRevert 2020Entirely. PleaseEntirely. Please2020-01-01https://lab.civicrm.org/dev/core/-/issues/5023Add aria-label to CheckBox, Radio and EntityRef in FormBuilder2024-02-21T17:59:01ZJoeMurrayAdd aria-label to CheckBox, Radio and EntityRef in FormBuilderModify
- [ ] CheckBox.html,
- [ ] Radio.html and
- [ ] EntityRef.html
in ext/afform/ang/af/fields/ to add aria-label="{{$ctrl.defn.label}} {{opt.label}}" to the input element's definition.
AGH tested these successfully with VoiceOve...Modify
- [ ] CheckBox.html,
- [ ] Radio.html and
- [ ] EntityRef.html
in ext/afform/ang/af/fields/ to add aria-label="{{$ctrl.defn.label}} {{opt.label}}" to the input element's definition.
AGH tested these successfully with VoiceOver on Safari on a Mac.
See Accessibility notes discussion of https://chat.civicrm.org/civicrm/pl/un7ajre7mbyc3fis4qebnczpse .JoeMurrayJoeMurrayhttps://lab.civicrm.org/dev/core/-/issues/4952PHP 8.3 Support2024-01-31T22:32:21ZJoeMurrayPHP 8.3 SupportThis is an epic for PHP 8.3 support.
PHP 8.3 was released 2023-11, has active support till 2024-12-8, and security support till 2025-12-08.
Some extra motivation to support 8.3 sooner rather that later is the significant performance im...This is an epic for PHP 8.3 support.
PHP 8.3 was released 2023-11, has active support till 2024-12-8, and security support till 2025-12-08.
Some extra motivation to support 8.3 sooner rather that later is the significant performance improvements it has, up to 55% for D10 over 8.1: https://kinsta.com/blog/php-benchmarks/
Reference: [https://www.php.net/manual/en/migration83.incompatible.php](https://www.php.net/manual/en/migration83.incompatible.php)
See also [thttps://php.watch/versions/8.3](https://php.watch/versions/8.3) and [https://www.php.net/releases/8.3/en.php](https://www.php.net/releases/8.3/en.php).
Here are the breaking changes listed here for reference. Almost all seem like they would be difficult to search for and identify in the codebase. Whack-a-mole from running on edge test servers might be a helpful approach.
- [ ] Uses of traits with static properties: Uses of traits with static properties will now redeclare static properties inherited from the parent class. This will create a separate static property storage for the current class. This is analogous to adding the static property to the class directly without traits.
- [ ] Assigning a negative index to an empty array: Assigning a negative index $n to an empty array will now make sure that the next index is $n+1 instead of 0.
- [ ] Class constant visibility variance check: Class constant visibility variance is now correctly checked when inherited from interfaces.
- [ ] WeakMap entries whose key maps to itself: WeakMap entries whose key maps to itself (possibly transitively) may now be removed during cycle collection if the key is not reachable except by iterating over the WeakMap (reachability via iteration is considered weak). Previously, such entries would never be automatically removed.
- [ ] Date: The DateTime extension has introduced Date extension specific exceptions and errors under the DateError and DateException hierarchies, instead of warnings and generic exceptions. This improves error handling, at the expense of having to check for errors and exceptions.
- [ ] DOM: Calling DOMChildNode::after(), DOMChildNode::before(), DOMChildNode::replaceWith() on a node that has no parent is now a no-op instead of a hierarchy exception, which is the behaviour demanded by the DOM specification.
Using the DOMParentNode and DOMChildNode methods without a document now works instead of throwing a DOM_HIERARCHY_REQUEST_ERR DOMException. This is in line with the behaviour demanded by the DOM specification.
Calling DOMDocument::createAttributeNS() without specifying a prefix would incorrectly create a default namespace, placing the element inside the namespace instead of the attribute. This bug is now fixed.
DOMDocument::createAttributeNS() would previously incorrectly throw a DOM_NAMESPACE_ERRNAMESPACE_ERR DOMException when the prefix was already used for a different URI. It now correctly chooses a different prefix when there's a prefix name conflict.
New methods and properties were added to some DOM classes. If a userland class inherits from these classes and declare a method or property with the same name, the declarations must be compatible. Otherwise, a typical compile error about incompatible declarations will be thrown. See the list of new features and new functions for a list of the newly implemented methods and properties.
- [x] FFI: C functions that have a return type of void now return null instead of returning the following object object(FFI\CData:void) { }
- [ ] Opcache: The opcache.consistency_checks INI directive was removed. This feature was broken with the tracing JIT, as well as with inheritance cache, and has been disabled without a way to enable it since PHP 8.1.18 and PHP 8.2.5. Both the tracing JIT and inheritance cache may modify shm after the script has been persisted by invalidating its checksum. The attempted fix skipped over the modifiable pointers but was rejected due to complexity. For this reason, it was decided to remove the feature instead.
- [ ] Phar: The type of Phar class constants are now declared.
- [ ] Standard: The range() function has had various changes:
A TypeError is now thrown when passing objects, resources, or arrays as the boundary inputs.
A more descriptive ValueError is thrown when passing 0 for $step.
A ValueError is now thrown when using a negative $step for increasing ranges.
If $step is a float that can be interpreted as an int, it is now done so.
A ValueError is now thrown if any argument is infinity or NAN.
An E_WARNING is now emitted if $start or $end is the empty string. The value continues to be cast to the value 0.
An E_WARNING is now emitted if $start or $end has more than one byte, only if it is a non-numeric string.
An E_WARNING is now emitted if $start or $end is cast to an integer because the other boundary input is a number. (e.g. range(5, 'z');).
An E_WARNING is now emitted if $step is a float when trying to generate a range of characters, except if both boundary inputs are numeric strings (e.g. range('5', '9', 0.5); does not produce a warning).
range() now produce a list of characters if one of the boundary inputs is a string digit instead of casting the other input to int (e.g. range('9', 'A');).
```
<?php
range('9', 'A'); // ["9", ":", ";", "<", "=", ">", "?", "@", "A"], as of PHP 8.3.0
range('9', 'A'); // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], prior to PHP 8.3.0
?>
```
The file() flags error check now catches all invalid flags. Notably FILE_APPEND was previously silently accepted.
- [ ] SNMP: The type of SNMP class constants are now declared.https://lab.civicrm.org/dev/core/-/issues/4921Add Soft Credit Recipient's and Contributor's Postal Address fields to includ...2024-01-29T10:13:28ZyashodhaAdd Soft Credit Recipient's and Contributor's Postal Address fields to include in the Soft Credit Report.Add Soft Credit Recipient's and Contributor's Postal Address fields to include in the Soft Credit Report. We already have phone/email having address would be helpful.Add Soft Credit Recipient's and Contributor's Postal Address fields to include in the Soft Credit Report. We already have phone/email having address would be helpful.https://lab.civicrm.org/dev/core/-/issues/4911Add params to actions when creating a WordPress User2024-01-12T17:45:30ZhaystackAdd params to actions when creating a WordPress UserOverview
----------------------------------------
The actions in the `CRM_Utils_System_WordPress::createUser()` method would be more helpful if they provided params when they fire. They were originally added to allow other code to know m...Overview
----------------------------------------
The actions in the `CRM_Utils_System_WordPress::createUser()` method would be more helpful if they provided params when they fire. They were originally added to allow other code to know merely *that* CiviCRM was creating a User (and to prevent recursion) but it would also be useful to know the source Contact and the resulting User ID in some cases.
Example use-case
----------------------------------------
A plugin that acts on a WordPress User when a Contact is added to a Group listens for `GroupContact.create` on the `civicrm_post` hook. Works just fine when using the CiviCRM back-end and the Contact and User both exist.
Current behaviour
----------------------------------------
The plugin will fail to act when a new Contact is added to a Group via a Contribution Page with a Profile that is configured to create a WordPress User. This is because the Contact is added to the Group _before_ the WordPress User is created.
Proposed behaviour
----------------------------------------
Although not an ideal solution to the problem, adding params to the actions in the `CRM_Utils_System_WordPress::createUser()` method would allow a plugin like the above to more easily identify the source Contact and the new User. The GroupContacts can then be checked and acted upon once the User has been created.
Comments
----------------------------------------
PR to follow.haystackhaystackhttps://lab.civicrm.org/dev/core/-/issues/4909Split 'Edit all contacts' permission2024-03-06T10:57:35ZGuillaumeSorelSplit 'Edit all contacts' permissionI jumped into a user case where some admin should be able to edit contacts they're allowed to manage but shouldn't be able to manage tags. After looking inside the documentation, stackexchange and the ACL I discovered that the 'Edit all ...I jumped into a user case where some admin should be able to edit contacts they're allowed to manage but shouldn't be able to manage tags. After looking inside the documentation, stackexchange and the ACL I discovered that the 'Edit all contacts' embeds several sub-permissions like editing the contacts information and also tags or groups. It's everything or nothing within this permission.
I'm not talking about the capability to manage Tags as entity (which as a separate permission) but to manage the use of them.
I think it could be interesting to split this permission with a 'edit all contacts' on the one hand and create a new 'edit contact tags / groups' on the other hand.https://lab.civicrm.org/dev/core/-/issues/4556"Check number" field isn't shown on Pending check payments (workaround exists)2023-12-12T19:08:26ZAllenShaw"Check number" field isn't shown on Pending check payments (workaround exists)(Similar to behavior described in https://lab.civicrm.org/dev/core/-/issues/60)
**One way to repro this on dmaster.demo.civicrm.org:**
1. Log in and navigate to any contact record.
2. Create and save a contribution with these attributes...(Similar to behavior described in https://lab.civicrm.org/dev/core/-/issues/60)
**One way to repro this on dmaster.demo.civicrm.org:**
1. Log in and navigate to any contact record.
2. Create and save a contribution with these attributes:
- Status: Pending
- Payment method: Check
3. Observe this contribution is displayed in the contact's Contributions tab.
4. Open the contribution for viewing, and select the "Record Payment" link or button; this opens the New Payment form.
5. In the New Payment form, observe that the Payment Method is pre-selected as "Check".
6. Observe expected vs actual (bad) behavior:
- Expected behavior: Because the Payment Method is "Check", the field "Check Number" should be displayed for data entry
- **Actual (bad) behavior:** "Check Number" field is not displayed.
**Workaround:**
Continuing from Step 6 above: Change the Payment Method to anything other than "Check", then change it back to "Check". Observe that the "Check Number" field is now available for data entry.
Screencap of problem and workaround from dmaster.demo.civicrm.org today:
![anim](/uploads/f951056d3c2c0c91aaff0d6f17a8b1b4/anim.gif)
(Joinery reference: F#1220)https://lab.civicrm.org/dev/core/-/issues/4547SearchKit: Edit in place for display name should be possible2023-09-03T00:16:46ZlarsssandergreenSearchKit: Edit in place for display name should be possibleIf you have a contact id in a SK display, enabling edit in place will show an autocomplete with contact names when clicked, but the field will show the contact id before clicking, which is confusing UI. On the other hand, a display name ...If you have a contact id in a SK display, enabling edit in place will show an autocomplete with contact names when clicked, but the field will show the contact id before clicking, which is confusing UI. On the other hand, a display name field shows the contact name as desired, but doesn't allow editing. So if you want to have an edit in place and show the contact name, you need both a contact id field and a display name field, which is confusing for the end user.
![image](/uploads/76c8542e1f32afac6074e817252e87ba/image.png)
Why should I click on the random integer on the right to edit the contact, instead of the name on the left?
Could we either make it possible to edit in place on the display name or make it possible to show the display name for the contact id field? Or maybe change the contact id field so it shows the display name by default, rename it to just contact, and add a separate field just for showing the contact id (which is probably a fairly rare need)?https://lab.civicrm.org/dev/core/-/issues/4533Searchkit: "Add new" button text2023-08-24T17:22:23Zmattwiremjw@mjwconsult.co.ukSearchkit: "Add new" button textWhen you enable the "Add New" button you cannot customise the text and it uses the entity name eg. "Add Activity". But if you want to link to a form that does something more specific eg. to create a signature on a petition it would be mu...When you enable the "Add New" button you cannot customise the text and it uses the entity name eg. "Add Activity". But if you want to link to a form that does something more specific eg. to create a signature on a petition it would be much clearer if this button could be customised to say eg. "Add Signature".https://lab.civicrm.org/dev/core/-/issues/4484Feature request: New contact buttons on the API 4 autocomplete widget2023-11-01T18:20:41ZbrienneFeature request: New contact buttons on the API 4 autocomplete widgetOverview
----------------------------------------
For using the APIv4 autocomplete widget, such as for the *Existing Contact* field, it would be useful to be able to create new contacts, as is possible with the Select2 drop downs, such a...Overview
----------------------------------------
For using the APIv4 autocomplete widget, such as for the *Existing Contact* field, it would be useful to be able to create new contacts, as is possible with the Select2 drop downs, such as for selecting a Contributor on a backend contribution.
![Selection_015](/uploads/30fc0ecdd3268ebc5906ce0aa06dae9a/Selection_015.png)
Example use-case
----------------------------------------
1. Add the *Existing Contact* field to a FormBuilder form
1. A user can look up a contact to select, but if there are no results/a new one is needed, they can click a **New Individual** button to add one without being redirected from the original form
Current behaviour
----------------------------------------
The APIv4 autocomplete widget does not allow for creating new contacts.
![Selection_014](/uploads/d97659f7dddfd4858bd316acb0dda2b6/Selection_014.png)
Proposed behaviour
----------------------------------------
The APIv4 autocomplete widget should have feature parity when it comes to creating new contacts on the spot as the Select2 optionhttps://lab.civicrm.org/dev/core/-/issues/4477Pay later instructions for offline event registration2023-08-07T01:50:54ZlarsssandergreenPay later instructions for offline event registrationIf you register a contact for an event on the back end, you can select Pending (Pay later) as the participant status and Pending as the contribution status. However, despite what you might expect the pay later instructions for the event ...If you register a contact for an event on the back end, you can select Pending (Pay later) as the participant status and Pending as the contribution status. However, despite what you might expect the pay later instructions for the event will not be sent in the offline event registration email, as `$is_pay_later` does not exist for offline registrations.
Presumably because it is copy-pasted from the online template, the offline event registration template does contain two conditionals for `$is_pay_later` (and so we get PHP warnings).
Option one, we remove `$is_pay_later` from the offline registration template. Simplification! No more warnings.
Option two, if participant status is Pending (pay later) and contribution status is Pending and the pay later instructions text exists for the event, we add the pay later instructions to the email. This is nice because it does what the user probably expects and it gives the registrant useful information to complete the payment. The downside is we are further perpetuating the arguably bad pay later concept, though we don't directly use is_pay_later. There is also added complexity for something that is probably not that common.https://lab.civicrm.org/dev/core/-/issues/4470Allow disabling household contact type2023-08-04T03:59:56ZlarsssandergreenAllow disabling household contact typeCurrent proposal:
Make it possible to disable household contact type.
Initial: These cannot be disabled. It would be nice to be able to disable them, especially households as many orgs do not use them. I know Spark has households disab...Current proposal:
Make it possible to disable household contact type.
Initial: These cannot be disabled. It would be nice to be able to disable them, especially households as many orgs do not use them. I know Spark has households disabled, so at least disabling households shouldn't break anything. Organizations might be different though and less important to allow disabling. Maybe worth trying to allow disabling households first and then see.https://lab.civicrm.org/dev/core/-/issues/4414CiviCRM 5.62.1 - CiviCRM core extension: Greenwich, Bootstrap CSS tries to lo...2023-08-08T22:21:55Zjustinfreeman (Agileware)CiviCRM 5.62.1 - CiviCRM core extension: Greenwich, Bootstrap CSS tries to load glyphicons fonts from the incorrect paths returns 404 and icons do not displayCiviCRM core extension: Greenwich, Bootstrap CSS tries to load glyphicons fonts from the incorrect paths returns 404 and icons do not display.
- civicrm/ext/greenwich/fonts/glyphicons-halflings-regular.woff2
- civicrm/ext/greenwich/font...CiviCRM core extension: Greenwich, Bootstrap CSS tries to load glyphicons fonts from the incorrect paths returns 404 and icons do not display.
- civicrm/ext/greenwich/fonts/glyphicons-halflings-regular.woff2
- civicrm/ext/greenwich/fonts/glyphicons-halflings-regular.woff
- civicrm/ext/greenwich/fonts/glyphicons-halflings-regular.ttf
Correct path is:
civicrm/ext/greenwich/extern/bootstrap3/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf
This error is shown in the Web Console when loading the Mosaico Template Editor to create or edit a Mailing.
civicrm/ext/greenwich/dist/bootstrap3.css
```
@font-face {
font-family: "Glyphicons Halflings";
src: url("../fonts/glyphicons-halflings-regular.eot");
src: url("../fonts/glyphicons-halflings-regular.eot?#iefix") format("embedded-opentype"), url("../fonts/glyphicons-halflings-regular.woff2") format("woff2"), url("../fonts/glyphicons-halflings-regular.woff") format("woff"), url("../fonts/glyphicons-halflings-regular.ttf") format("truetype"), url("../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular") format("svg");
}
```
Version: CiviCRM 5.62.1
Agileware Ref: CIVICRM-2149https://lab.civicrm.org/dev/core/-/issues/4397What should the Name and Address reserved general Individual dedupe rule do?2023-06-30T00:14:21ZlarsssandergreenWhat should the Name and Address reserved general Individual dedupe rule do?We have a reserved dedupe rule on new installs for Individuals called Name and Address.
What it actually does is matches contacts who have the same first name, last name and street address. What it claims to do is the following:
![image]...We have a reserved dedupe rule on new installs for Individuals called Name and Address.
What it actually does is matches contacts who have the same first name, last name and street address. What it claims to do is the following:
![image](/uploads/d427acb2b1c3ce07c994b68a2371ac62/image.png)
[This rule](https://github.com/civicrm/civicrm-core/blob/master/sql/civicrm_data/civicrm_dedupe_rule/IndividualGeneral.sqldata.php) also includes suffix_id and middle_name with weights of 1, which cannot influence the matches (threshold 15, all other items have weight 5), so these don't do anything.
There is a [hard-coded query](https://github.com/civicrm/civicrm-core/blob/master/CRM/Dedupe/BAO/QueryBuilder/IndividualGeneral.php) for this rule that should match up with the above (right now we are querying middle_name, suffix and birthdate for no reason, which is kind of ironic since this query claims to be optimized).
None of this has changed in at least ten years.
Personally, I don't think matching on first, last and street address is useful (as street addresses are often written slightly differently so are not that likely to match). Maybe we should just eliminate this reserved dedupe rule, since I can't see that it is used for anything. If not, maybe we should make it more useful by making it just first and last name. Or maybe there is some reason this is useful as is and we should simply make this all consistent so it just matches on first, last and address and nothing more.https://lab.civicrm.org/dev/core/-/issues/4361Add Pay now link to Invoice template2023-06-28T06:58:22ZlarsssandergreenAdd Pay now link to Invoice templateIt would be nice to have the link to pay online included in the Invoice template. Currently, a user would have to guess this is possible, find the correct link on SE and add it to the template (then maintain it as the template is updated...It would be nice to have the link to pay online included in the Invoice template. Currently, a user would have to guess this is possible, find the correct link on SE and add it to the template (then maintain it as the template is updated).
I think if default_invoice_page is set, we could simply include a Pay Now link in the Payment Advice section (which is only shown if the Contribution is pending and pay later). If an org doesn't want to include a link for online payment, they can simply leave default_invoice_page empty (Edit: They cannot currently do this for newer installs, will have to make it possible). I think it would be very rare for an org to want to have a default_invoice_page for payments from the User Dashboard, but not to include a link for online payments in invoices (and in that case, they can edit the template).
Will do this and add docs if supported.https://lab.civicrm.org/dev/core/-/issues/4342It should be possible to remove a hidden smart group from recipients of a mai...2023-06-28T06:56:18ZlarsssandergreenIt should be possible to remove a hidden smart group from recipients of a mailing that has been copiedIf you create a mailing by copying another mailing that was sent to search results, it is impossible to remove the hidden smart group from the recipients of your new mailing. This can be frustrating, because your intent in copying a mail...If you create a mailing by copying another mailing that was sent to search results, it is impossible to remove the hidden smart group from the recipients of your new mailing. This can be frustrating, because your intent in copying a mailing may not have been to send it to the same contacts, rather to re-use the content. With Mosaico, you can't easily duplicate the content, so this is a pain.
Ideally, hidden smart groups would be mandatory for the original mailing and could be removed for copies. However, that isn't possible because mandatory groups are simply [included groups that are hidden](https://github.com/civicrm/civicrm-core/blob/f0648c892ab4795b9bec873c840e06009ea4800a/ang/crmMailing/BlockRecipients.html#L6).
Options I see:
1. Don't include hidden groups when copying a mailing. Would solve this issue, but then some users are going to expect identical recipients when they copy a mailing because they are copying the mailing in order to resend to the same recipients, changing the content.
1. Add a Copy without recipients option. This seems like it would add UI complexity for something pretty specific.
2. Allow hidden smart groups to be removed from mailings in general, with a confirmation. This feels like the best option to me. Maybe I've started a mailing from search results and later decide I don't want to send it to those search results. Clearly we want to prevent users from removing a hidden group by accident, but as an intentional decision the user confirms, I think this makes sense. Would have to look at how to handle the unsubscribe group in this case.