Development issueshttps://lab.civicrm.org/groups/dev/-/issues2023-11-24T22:45:42Zhttps://lab.civicrm.org/dev/core/-/issues/2796Regression? No way to change the tax rate and tax amount using buildamount hook2023-11-24T22:45:42ZPradeep Nayakpradpnayak@gmail.comRegression? No way to change the tax rate and tax amount using buildamount hookIn 5.35.x LineItem create api allowed one to set a different tax_amount in api params for a financial type that had tax enabled. The tax amount could then be calculated programatically based on region, location etc instead of using the c...In 5.35.x LineItem create api allowed one to set a different tax_amount in api params for a financial type that had tax enabled. The tax amount could then be calculated programatically based on region, location etc instead of using the config specified in the UI.
```
civicrm_api3('LineItem', 'create', [
'entity_id' => 284,
'qty' => 1,
'unit_price' => 100,
'line_total' => 100,
'entity_table' => "civicrm_contribution",
'tax_amount' => 20,
'financial_type_id' => "Donation",
'price_field_id' => "contribution_amount",
'price_field_value_id' => "single",
]);
```
Another way of calculating tax on online forms was using the [buildamount hook](https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_buildAmount/)
```
function advanceinvoicing_civicrm_buildAmount($pageType, &$form, &$amount) {
$amount[$priceFieldId]['options'][$priceFieldValueId]['tax_rate'] = 10;
$amount[$priceFieldId]['options'][$priceFieldValueId]['tax_amount'] = 0.1;
}
```
A recent [change](https://github.com/civicrm/civicrm-core/commit/e967ce8fe2b#diff-a16d4d7449cf5f3a0616d1d282a32f27ab6d3f7d2726d076c02ad1d4d655af41R56) to the line item create function has stopped allowing tax amount to be set programmatically.
Is this intentional? Is there any way to support different tax rate for single financial type?https://lab.civicrm.org/dev/core/-/issues/2795PHP8: Use of error-suppression operator (@) behaves differently in error_hand...2023-12-12T19:51:20ZDaveDPHP8: Use of error-suppression operator (@) behaves differently in error_handler functions in php8Parking what's left in https://github.com/civicrm/civicrm-core/pull/21064 here for now since I've cleared out a bunch and am taking a break from it. The gist is that in php8 the error suppression operator (e.g. `@fopen('/nonexistent/file...Parking what's left in https://github.com/civicrm/civicrm-core/pull/21064 here for now since I've cleared out a bunch and am taking a break from it. The gist is that in php8 the error suppression operator (e.g. `@fopen('/nonexistent/file.txt', 'r')` works differently with respect to error_handler functions. In a stock install as of right now you won't notice any difference, just there will be more errors depending on what 3rd party/custom error_handlers you're using and may behave differently on different CMSs in future depending on how their error-handling may change.
### smarty default modifier
The smarty modifier `|default` is a tricky one because its whole purpose is to deal with the situation where the var might be missing, but the way smarty compiles it is something like `<?php $this->assign('to', ((is_array($_tmp=@$this->_tpl_vars['to'])) ? $this->_run_mod_handler('default', true, $_tmp, '_high') : smarty_modifier_default($_tmp, '_high'))); ?>` which uses the @ to try to silence the error. In addition to [templates/CRM/Core/DatePickerRange.tpl and templates/CRM/Core/DatePickerRangeWrapper.tpl](https://github.com/civicrm/civicrm-core/commit/f671f500b658aa772fedc682dbb320cf456bc904), the below are all instances of this. They could all be rewritten to not use the modifier, but the modifier itself is part of smarty so can't easily be prevented from being used in future.
* CRM_Core_InvokeTest::testInvokeDashboardForNonAdmin
* CRM/Contact/Page/DashboardDashlet.tpl - $communityMessages
* CRM_Core_SessionTest::testSetStatusWithTextOnly
* CRM/common/info.tpl
* CRM_Core_SessionTest::testSetStatusWithTitleOnly
* CRM/common/info.tpl
* CRM_Core_SessionTest::testSetStatusWithBoth
* CRM/common/info.tpl
### opendir
```
CRM_Utils_File::cleanDir
if ($dh = @opendir($target)) {
```
### unlink and mkdir
Various calls to `@unlink` and `@mkdir`
### httpclient
```
CRM_Utils_HttpClientTest::testFetchHttp_badOutFile
Exception: fopen(/ba/d/path/too/utput): Failed to open stream: No such file or directory
...\tests\phpunit\CiviTest\CiviUnitTestCase.php:253
...\CRM\Utils\HttpClient.php:79 <---- see here
...\tests\phpunit\CRM\Utils\HttpClientTest.php:77
...\tests\phpunit\CiviTest\CiviUnitTestCase.php:267
...\phpunit8:671
```
### angular changeset
Aside: The code in question here suggests phpQuery has its own debug setting which maybe could be turned on automatically in future if you have civi debugging enabled:
`$return = phpQuery::$debug === 2 ? this->document->loadHTML($markup) : @$this->document->loadHTML($markup);`
```
Civi\Angular\ChangeSetTest::testInsertAfter
Exception: DOMDocument::loadHTML(): htmlParseEntityRef: no name in Entity, line: 2
...\tests\phpunit\CiviTest\CiviUnitTestCase.php:253
...\vendor\electrolinux\phpquery\phpQuery\phpQuery\DOMDocumentWrapper.php:200
...\vendor\electrolinux\phpquery\phpQuery\phpQuery\DOMDocumentWrapper.php:542
...\vendor\electrolinux\phpquery\phpQuery\phpQuery\DOMDocumentWrapper.php:505
...\vendor\electrolinux\phpquery\phpQuery\phpQuery\DOMDocumentWrapper.php:469
...\vendor\electrolinux\phpquery\phpQuery\phpQuery\phpQueryObject.php:2066
...\vendor\electrolinux\phpquery\phpQuery\phpQuery\phpQueryObject.php:2010
...\tests\phpunit\Civi\Angular\ChangeSetTest.php:28
...\Civi\Angular\ChangeSet.php:59
...\Civi\Angular\ChangeSet.php:19
...\tests\phpunit\Civi\Angular\ChangeSetTest.php:39
...\tests\phpunit\CiviTest\CiviUnitTestCase.php:267
...\phpunit8:671
```
* not ok 103 - Error: Civi\Angular\PartialSyntaxTest::testConsistencyExamples with data set 6 `('<div ng-if="a && b"></div>', '<div ng-if="a && b"></div>')`
* not ok 104 - Error: Civi\Angular\PartialSyntaxTest::testAllPartials
* These are the same issue as the changeset tests.
### testing of deprecations
These deliberately test deprecations
* not ok 223 - Error: Civi\Payment\PropertyBagTest::testSetContactIDLegacyWay
* not ok 227 - Error: Civi\Payment\PropertyBagTest::testSetCustomProp
### testGetfieldsHasTitle
```
api_v3_SyntaxConformanceTest::testGetfieldsHasTitle with data set 32 ('Entity')
Failure in api call for Entity getactions: include_once(api/v3/batch_create.php): failed to open stream: No such file or directory
0 ...\api\v3\Entity.php(18): CiviUnitTestCase->letssee(2, 'include_once(ap...', '\path\to\...', 18, Array)
1 ...\api\v3\Entity.php(18): include_once()
2 ...\api\v3\utils.php(2461): _civicrm_api3_entity_deprecation(Array)
3 ...\api\v3\utils.php(251): _civicrm_api3_deprecation_check('Entity', Array)
4 ...\Civi\API\Provider\ReflectionProvider.php(108): civicrm_api3_create_success(Array, Array, 'Entity', 'getactions')
5 ...\Civi\API\Kernel.php(149): Civi\API\Provider\ReflectionProvider->invoke(Array)
6 ...\Civi\API\Kernel.php(81): Civi\API\Kernel->runRequest(Array)
7 ...\api\api.php(22): Civi\API\Kernel->runSafe('Entity', 'getactions', Array)
8 ...\Civi\Test\Api3TestTrait.php(292): civicrm_api('Entity', 'getactions', Array)
9 ...\Civi\Test\Api3TestTrait.php(173): CiviUnitTestCase->civicrm_api('Entity', 'getactions', Array)
10 ...\tests\phpunit\api\v3\SyntaxConformanceTest.php(1662): CiviUnitTestCase->callAPISuccess('Entity', 'getactions', Array)
11 phar://.../phpunit8/phpunit/Framework/TestCase.php(1213): api_v3_SyntaxConformanceTest->testGetfieldsHasTitle('Entity')
12 ...\tests\phpunit\CiviTest\CiviUnitTestCase.php(267): PHPUnit\Framework\TestCase->runTest()
13 phar://.../phpunit8/phpunit/Framework/TestCase.php(889): CiviUnitTestCase->runTest()
14 phar://.../phpunit8/phpunit/Framework/TestResult.php(577): PHPUnit\Framework\TestCase->runBare()
15 phar://.../phpunit8/phpunit/Framework/TestCase.php(663): PHPUnit\Framework\TestResult->run(Object(api_v3_SyntaxConformanceTest))
16 phar://.../phpunit8/phpunit/Framework/TestSuite.php(481): PHPUnit\Framework\TestCase->run(Object(PHPUnit\Framework\TestResult))
17 phar://.../phpunit8/phpunit/Framework/TestSuite.php(481): PHPUnit\Framework\TestSuite->run(Object(PHPUnit\Framework\TestResult))
18 phar://.../phpunit8/phpunit/TextUI/TestRunner.php(462): PHPUnit\Framework\TestSuite->run(Object(PHPUnit\Framework\TestResult))
19 phar://.../phpunit8/phpunit/TextUI/Command.php(129): PHPUnit\TextUI\TestRunner->doRun(Object(PHPUnit\Framework\TestSuite), Array, Array, true)
20 phar://.../phpunit8/phpunit/TextUI/Command.php(101): PHPUnit\TextUI\Command->run(Array, true)
21 ...\phpunit8(671): PHPUnit\TextUI\Command::main()
22 {main}
Failed asserting that a integer is empty.
...\Civi\Test\Api3TestTrait.php:110
...\Civi\Test\Api3TestTrait.php:174
...\tests\phpunit\api\v3\SyntaxConformanceTest.php:1662
...\tests\phpunit\CiviTest\CiviUnitTestCase.php:267
...\phpunit8:671
```
### mailing testConcurrency
This doesn't run properly on windows even without the error_handler, and I don't feel like taking the time right now to deal with that:
not ok 1161 - Error: api_v3_JobProcessMailingTest::testConcurrency with data set #0 (array(20, 3, 10, 4, 1), array(2, 1), 4)https://lab.civicrm.org/dev/core/-/issues/2788Add tokenlist api2023-09-24T22:53:09ZeileenAdd tokenlist apiWe need an api to call via ajax to determine the available tokens for a given entity. An example is the Scheduled reminders UI which currently presents the tokens for all entities (available or not) but would ideally look up the tokens v...We need an api to call via ajax to determine the available tokens for a given entity. An example is the Scheduled reminders UI which currently presents the tokens for all entities (available or not) but would ideally look up the tokens via ajax once the entity is selected.
I think the hardest part of doing this is agreeing how it should look - eg. entity, action, parameters - eg
```
Civi\Api4\Tokens::list()
->setSchema(['contributionId', 'contactId')
->setWhere('contact_type', '=', 'Organization')
->execute();
```
Possible entity names
- Token
- Tokens
- TokenProcessor
- EntityTokens
Possible actions
-list
- getTokens
- listTokens
Schema - maybe this one is clear cut
And - how do we pass relatively free form tokens such as activity_type_id, contact_type or (possibly in the future) saved_search_id where search kit plays a rolehttps://lab.civicrm.org/dev/financial/-/issues/182Possible regression - civicrm_line_item.line_total is incorrectly tax inclusi...2023-11-23T07:17:29ZeileenPossible regression - civicrm_line_item.line_total is incorrectly tax inclusive - potentially 5.39+In 5.39 there was a fix to stop the situation where the contribution.total_amount was recalculated on edit when tax was involved. However this fix had a bug and civicrm_line_item.line_total [stored the tax INCLUSIVE amount](see https://...In 5.39 there was a fix to stop the situation where the contribution.total_amount was recalculated on edit when tax was involved. However this fix had a bug and civicrm_line_item.line_total [stored the tax INCLUSIVE amount](see https://github.com/civicrm/civicrm-core/commit/e967ce8fe2b58b94e2163dde395542e55599da13#diff-4c9d0b1abe07057a4eea2b47bc627eecb95face8ed8d86c1c005312a52cca811L4026-L4035) We [have merged a fix to the rc](https://github.com/civicrm/civicrm-core/pull/21212) but I opened this to try to determine if any released versions are affected. This rose to a bigger issue in the rc because of changes on top of it - which assumed it was right.
The reason this went awol is largely because we had too behaviours - if the contribution bao didn't receive tax_amount it treated total_amount as exclusive and if it did it treated it as inclusive. The former was locked in by tests & not the latter leading to confusion (I'm still confused)
At this stage I'm unsure about real-world issues with this as
1) it didn't affect any core forms that I'm aware of as they pass in 'line_item' or 'skipLineItem'
2) this was the 'correct' behaviour historically for Contribution.create api calls that should have tax_amount passed in, but didn't
3) we have a [deprecation notice](https://github.com/civicrm/civicrm-core/commit/e967ce8fe2b58b94e2163dde395542e55599da13#diff-4c9d0b1abe07057a4eea2b47bc627eecb95face8ed8d86c1c005312a52cca811R193) in the code that would likely have been triggered if line item tax totals did not add up to contribution totals & it's unlikely people would miss wrong contribution totals.
However, my head breaks a bit when I try to think through this
I *think* this would pick up any wrong rows
```
SELECT
SUM(li.line_total + li.tax_amount) as lines_total,
count(li.id) as c,
SUM(c.total_amount) as total_amount
FROM civicrm_contribution c LEFT JOIN civicrm_line_item li ON li.contribution_id = c.id
GROUP BY c.id
HAVING c > 1
AND lines_total <> total_amount
```https://lab.civicrm.org/dev/core/-/issues/2775Scheduled reminders fail silently if there is an error in the template2023-03-27T16:26:57ZwmortadaScheduled reminders fail silently if there is an error in the templateOverview
----------------------------------------
We have recently come across an issue whereby scheduled reminders weren't being sent but we were completely unaware this was happening. We managed to track it down to an error in the temp...Overview
----------------------------------------
We have recently come across an issue whereby scheduled reminders weren't being sent but we were completely unaware this was happening. We managed to track it down to an error in the template for one of the event reminders we had set up - the template contained CSS and this caused a fatal error in Smarty.
```
PHP Fatal error: Smarty error: [in string:<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title></title>
<style type="text/css">html { font-size: 100%;}
html, button, input, select, textarea { font-family: sans-serif; }
body, h1, h2, h3, h4, h5, h6, p { margin: 0; }
table { border-collapse: collapse; border-spacing: 0; }
td img { display: block; }
...
```
The issue is that this stopped _all_ scheduled reminders from being sent - not just the event reminder. This meant that none of our membership renewal reminder emails were being sent either. We were completely unaware of this because there was no visible error message in the UI.
Reproduction steps
----------------------------------------
1. Create a scheduled reminder that works correctly.
1. Check that this is sending emails as expected.
1. Create another scheduled reminder with CSS in the template (see above) so that it causes a Smarty error.
1. Note that none of the scheduled reminder emails are being sent.
Current behaviour
----------------------------------------
CiviCRM fails silently when there is an error in a template for a scheduled reminder. This stops all scheduled reminders from being sent.
Expected behaviour
----------------------------------------
There are several things that should happen if there is an error in a Smarty template:
1. CiviCRM alerts the user at the point of creating/editing a scheduled reminder with a Smarty error in the template.
1. CiviCRM alerts the user if there is scheduled reminders fail to be sent - see #1933.
1. CiviCRM should continue to send the other scheduled reminders as normal so only the reminder with an error fails, rather than no reminders being sent at all.
Environment information
----------------------------------------
* __Browser:__ N/A
* __CiviCRM:__ _5.33.5_
* __PHP:__ _7.3_
* __CMS:__ _WordPress 5.4.6_
* __Database:__ _Maria DB 10.3.23._
* __Web Server:__ _Nginx 1.15.0_
Comments
-----------------------------------------
See this post on StackExchange for info about the Smarty error: [SMARTY error with template](https://civicrm.stackexchange.com/questions/31866/smarty-error-with-template).https://lab.civicrm.org/dev/user-interface/-/issues/39Email Signature: changing the "from" email does not update the signature2021-08-17T03:40:42ZbgmEmail Signature: changing the "from" email does not update the signatureFrom #38:
> The signature doesn't change when you change the FROM address on the email form.
To reproduce:
* Add a second email to your contact record
* Add different signatures to both emails
* Click to send an email (it can be to se...From #38:
> The signature doesn't change when you change the FROM address on the email form.
To reproduce:
* Add a second email to your contact record
* Add different signatures to both emails
* Click to send an email (it can be to self, does not matter)
* Primary email signature is loaded
* Change the "from" email to the secondary email (of our logged-in user)
* Notice that the signature did not change.
Tangential:
* Loading a message template removes the email signature. Kind of annoying.
* Switching from/signatures could assume that we are reloading the content, but should probably warn that the content is about to be lost.
cc @DaveD @justinfreemanhttps://lab.civicrm.org/dev/financial/-/issues/179Search kit bugs2021-08-04T22:27:21ZeileenSearch kit bugs@colemanw I hit a couple of things writing up about [how to do a payments search](https://docs.google.com/document/d/1OM8T-HsqFQDVGMB83iXx6CkC4mtRh4dA0hNK0MIX4hc/edit#)
I figured I'd just stick them in one ticket for now
1) The amount...@colemanw I hit a couple of things writing up about [how to do a payments search](https://docs.google.com/document/d/1OM8T-HsqFQDVGMB83iXx6CkC4mtRh4dA0hNK0MIX4hc/edit#)
I figured I'd just stick them in one ticket for now
1) The amount column from the financial_trxn table was not available to add as an afform filter
![image](/uploads/3608db6fc7f5c8289b4f276d40396927/image.png)
2) It 'looked' like I could make check_number 'edit-in-placeable' on the financial_trxn table - but it didn't work - note that check_number IS a field that should be editable as a data entry issue with no financial transaction implications (if we were editing payment method I think we would to be sure that the edit-in-place is calling v3 Payment.create not v4 FinancialTrxn.create - the former is a wrapper for the latter with more logic)
![image](/uploads/67ed36272f37bbc2fe9bdeacbe199c5d/image.png)
![image](/uploads/58fab89fd8ca820dfb2f17a0a4ffa726/image.png)https://lab.civicrm.org/dev/core/-/issues/2693Remove all calls to BAO_Contribution::completeOrder other than from Payment.c...2023-09-10T15:41:47ZeileenRemove all calls to BAO_Contribution::completeOrder other than from Payment.createThe goal is that we should either
1) call Payment.create to add a payment - which would itself call completeOrder
2) OR call repeatTransaction via the repeattransaction api to create a pending order - which we would then update to cance...The goal is that we should either
1) call Payment.create to add a payment - which would itself call completeOrder
2) OR call repeatTransaction via the repeattransaction api to create a pending order - which we would then update to cancelled or failed if need be or - if completed call payment.create
Note that currently Payment.create calls Contribution.completetransaction - the goal is to reverse this
I'm currently working on removing calls to completeOrder other than from the 2 api calls - at which point we can change the api calls to no longer call completeOrder directlyhttps://lab.civicrm.org/dev/financial/-/issues/177Batch Transactions: Search cannot filter by Soft-Credit2023-07-21T17:13:51ZmhowisonBatch Transactions: Search cannot filter by Soft-CreditI'm trying to create a batch of existing contacts who have all made a contribution via Donor-Advised Fund (DAF).
When I use the Find Contributions search feature, I'm able to produce a list of contacts who gave through Donor-Advised Fun...I'm trying to create a batch of existing contacts who have all made a contribution via Donor-Advised Fund (DAF).
When I use the Find Contributions search feature, I'm able to produce a list of contacts who gave through Donor-Advised Funds in FY21 (Date Received=Previous Fiscal Year, Contributions AND Their Soft Credits, Soft Credit Type=Donor-Advised Fund).
However, when I run this same query through the search feature in the 'add existing transactions to a batch' screen, the results are incorrect. It filters for previous fiscal year contributions, but it returns all contributions rather than just contributions with a soft credit type of DAF.
The Soft Credit Type criteria doesn't seem to be registering. This shows you the 'add existing transactions to a batch' screen I'm referring to: (https://docs.civicrm.org/user/en/latest/contributions/accounting-integration/#create-a-new-batch-from-existing-transactions.)https://lab.civicrm.org/dev/financial/-/issues/176Billing fields aren't hidden even when they can2024-02-19T16:44:11ZcapoBilling fields aren't hidden even when they canThe **assignAddressField** function, implemented in [CRM/Core/BAO/UFField.php#L785](https://github.com/civicrm/civicrm-core/blob/master/CRM/Core/BAO/UFField.php#L785), is meant to return a boolean that tells if:
> Can the address block ...The **assignAddressField** function, implemented in [CRM/Core/BAO/UFField.php#L785](https://github.com/civicrm/civicrm-core/blob/master/CRM/Core/BAO/UFField.php#L785), is meant to return a boolean that tells if:
> Can the address block be hidden safe in the knowledge all fields are elsewhere collected (see CRM-15118)
But it only has one return statement when that covers some of the cases in which the fields can't be hidden. In other words, the function never returns true. It can let JavaScript know that all the necessary fields are present but it can't let know other PHP functions.
This issue might be related with #129.https://lab.civicrm.org/dev/core/-/issues/2669Target contact missing for automatically generated case activities2023-02-23T16:00:45ZAndreasandreas.howiller@civiservice.deTarget contact missing for automatically generated case activitiesOverview
----------------------------------------
Some actions on cases leave automatically generated activities in the case activity log, but have no target contacts. Examples: Change case title, change case tags. As a result, they cann...Overview
----------------------------------------
Some actions on cases leave automatically generated activities in the case activity log, but have no target contacts. Examples: Change case title, change case tags. As a result, they cannot be edited through the user interface. While this is a minor issue, some users may want to leave notes about the activity (for example, why they changed a case title) and therefore need to edit it.
Reproduction steps
----------------------------------------
1. Open any case in CiviCRM and change the case title.
2. Tap edit for the corresponding activity in the activity timeline.
3. Tap save.
Current behaviour
----------------------------------------
The dialog will freeze while the CiviCRM logo keeps turning. A fatal error "DB Error: constraint violation" will be filed in the logs.
If you add any contact as a target contact in the database or in the edit screen the error won't appear anymore.
What is confusing, too: When editing the activity the client contact already wrongly shows up as target contact in this dialog and if you'd like to change it there you need to search the contact (the link to choose the client contact below the search field won't do the change here).
Expected behaviour
----------------------------------------
The Client contact is filed as target contact by default and connected problems disappear. E.g. editable activities can be saved after edit through UI now.
Environment information
----------------------------------------
* __CiviCRM:__ _5.35.2_ and _5.38.0_
* __CMS:__ _WordPress 5.7.2_https://lab.civicrm.org/dev/core/-/issues/2651CivicrmBreadcrumbBuilder is getting invalid URLs and breaking2023-09-29T13:46:29ZananelsonCivicrmBreadcrumbBuilder is getting invalid URLs and breakingOverview
----------------------------------------
I ran into this exception while trying to open most any page in CiviCase (using compucorp's CiviCase but I don't think that matters).
InvalidArgumentException: The user-entered string '...Overview
----------------------------------------
I ran into this exception while trying to open most any page in CiviCase (using compucorp's CiviCase but I don't think that matters).
InvalidArgumentException: The user-entered string 'https://example.com/civicrm/case/a/?case_type_category=1#/case?case_type_category=1' must begin with a '/', '?', or '#'. in Drupal\Core\Url::fromUserInput() (line 213 of core/lib/Drupal/Core/Url.php).
I found that the breadcrumbs list contained:
- /
- /civicrm?reset=1
- https://example.com/civicrm/case/a/?case_type_category=1#/case?case_type_category=1
So somehow the items being added to breadcrumbs list weren't getting parsed correctly. I worked around this temporarily by modifying the build() function to only add valid items:
```
public function build(RouteMatchInterface $route_match) {
$breadcrumb = new Breadcrumb();
$breadcrumb->addCacheContexts(['url']);
$breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));
foreach ($this->civicrmPageState->getBreadcrumbs() as $name => $url) {
// All urls here have been passed trough CRM_Utils_System::url, so we have
// to parse and decode them before creating a drupal Url object.
> if (substr($url, 0, 1) == "/") {
$url = Url::fromUserInput(html_entity_decode($url));
$breadcrumb->addLink(new Link($name, $url));
> }
}
return $breadcrumb;
}
```
Since it's not a big deal to me to not have the current page in breadcrumbs, and this was an easy way to fix.
I'm not sure how the invalid url was added to the breadcrumbs, and whether that's happening in the extension or in core, but it does seem like a little checking to be sure an invalid breadcrumb doesn't cause the whole page to break would be useful in core.
Environment information
----------------------------------------
* __CiviCRM:__ _5.38.0_https://lab.civicrm.org/dev/core/-/issues/2646Enable/Disable Extension Receives API Error2022-09-16T00:12:46ZpbarmakEnable/Disable Extension Receives API ErrorOverview
----------------------------------------
Anytime we enable or disable an extension, we get an API error with the error message of: API error: Value already exists in the database on ReportTemplate.create. This is true with eithe...Overview
----------------------------------------
Anytime we enable or disable an extension, we get an API error with the error message of: API error: Value already exists in the database on ReportTemplate.create. This is true with either the Admin extension UI screen or using cv.
Reproduction steps
----------------------------------------
1. Run cv ext:disable uk.co.vedaconsulting.mosaico
2. Get the error message
3. The extension still gets disabled (or enabled, depending on what we run)
Current behaviour
----------------------------------------
Here is the full error message from cv:
```
Disabling extension "uk.co.vedaconsulting.mosaico"
Error: API Call Failed: Array
(
[entity] => Extension
[action] => disable
[params] => Array
(
[keys] => Array
(
[0] => uk.co.vedaconsulting.mosaico
)
[debug] => 1
[version] => 3
)
[result] => Array
(
[trace] => #0 /var/www/civicrm/sites/all/modules/civicrm/CRM/Core/ManagedEntities.php(241): CRM_Core_ManagedEntities->onApiError('ReportTemplate', 'create', Array, Array)
#1 /var/www/civicrm/sites/all/modules/civicrm/CRM/Core/ManagedEntities.php(184): CRM_Core_ManagedEntities->insertNewEntity(Array)
#2 /var/www/civicrm/sites/all/modules/civicrm/CRM/Core/ManagedEntities.php(146): CRM_Core_ManagedEntities->reconcileEnabledModule(Object(CRM_Core_Module), Array)
#3 /var/www/civicrm/sites/all/modules/civicrm/CRM/Core/ManagedEntities.php(127): CRM_Core_ManagedEntities->reconcileEnabledModules()
#4 /var/www/civicrm/sites/all/modules/civicrm/CRM/Core/Invoke.php(400): CRM_Core_ManagedEntities->reconcile()
#5 /var/www/civicrm/sites/all/modules/civicrm/CRM/Extension/Manager.php(420): CRM_Core_Invoke::rebuildMenuAndCaches(true)
#6 /var/www/civicrm/sites/all/modules/civicrm/api/v3/Extension.php(150): CRM_Extension_Manager->disable(Array)
#7 /var/www/civicrm/sites/all/modules/civicrm/Civi/API/Provider/MagicFunctionProvider.php(89): civicrm_api3_extension_disable(Array)
#8 /var/www/civicrm/sites/all/modules/civicrm/Civi/API/Kernel.php(149): Civi\API\Provider\MagicFunctionProvider->invoke(Array)
#9 /var/www/civicrm/sites/all/modules/civicrm/Civi/API/Kernel.php(81): Civi\API\Kernel->runRequest(Array)
#10 /var/www/civicrm/sites/all/modules/civicrm/api/api.php(22): Civi\API\Kernel->runSafe('Extension', 'disable', Array)
#11 phar:///usr/local/bin/cv/src/Command/BaseCommand.php(49): civicrm_api('Extension', 'disable', Array)
#12 phar:///usr/local/bin/cv/src/Command/ExtensionDisableCommand.php(56): Civi\Cv\Command\BaseCommand->callApiSuccess(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput), 'Extension', 'disable', Array)
#13 phar:///usr/local/bin/cv/vendor/symfony/console/Command/Command.php(257): Civi\Cv\Command\ExtensionDisableCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#14 phar:///usr/local/bin/cv/vendor/symfony/console/Application.php(850): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#15 phar:///usr/local/bin/cv/vendor/symfony/console/Application.php(193): Symfony\Component\Console\Application->doRunCommand(Object(Civi\Cv\Command\ExtensionDisableCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#16 phar:///usr/local/bin/cv/src/Application.php(46): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#17 phar:///usr/local/bin/cv/vendor/symfony/console/Application.php(124): Civi\Cv\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#18 phar:///usr/local/bin/cv/src/Application.php(15): Symfony\Component\Console\Application->run()
#19 phar:///usr/local/bin/cv/bin/cv(27): Civi\Cv\Application::main('phar:///usr/loc...')
#20 /usr/local/bin/cv(14): require('phar:///usr/loc...')
#21 {main}
[is_error] => 1
[error_message] => API error: Value already exists in the database on ReportTemplate.create
)
)
```
Expected behaviour
----------------------------------------
No error message
Environment information
----------------------------------------
* __CiviCRM:5.38.0
* __PHP:7.3.28
* __CMS:Drupal 7
* __Web Server: Apache 2.4https://lab.civicrm.org/dev/core/-/issues/2641Users affected by ACLs intermittently lose access to contacts2023-08-22T04:01:30ZjhungerfordUsers affected by ACLs intermittently lose access to contactsOverview
----------------------------------------
When a user's permission to view Contacts is affected by multiple ACLs, they will intermittently lose access to some of them, especially directly after editing a record.
Reproduction ste...Overview
----------------------------------------
When a user's permission to view Contacts is affected by multiple ACLs, they will intermittently lose access to some of them, especially directly after editing a record.
Reproduction steps
----------------------------------------
1. Create a test User who is not an Administrator and does not have "view all contacts" or "edit all contacts" permission
2. Create two Groups (of type Access Control List), and add the test User to both groups
3. Create two Groups (not of ACL type) with distinct names like "Contact Group1" and "Contact Group2"
4. Create two Contacts and add one to each of the Groups created in step 3
5. Create two ACLs, each giving users in one of the ACL groups access to one of the Contact groups
6. Log in as the test User and repeatedly edit the Nickname (or any other data) on both of the test Contacts until you encounter a failure ("Error You do not have the necessary permission to view this contact").
It will rarely take more than ten edits before you encounter a failure, and the failures will never occur for one of the ACL groups.
Current behaviour
----------------------------------------
Sometimes it works, sometimes the user loses permission during the save or reload operation, resulting in the error message below. Our users reported that usually the data would be saved, but sometimes not (e.g. when saving some Activities on a Case). I have not been able to replicate the data loss scenario.
```
Error
You do not have the necessary permission to view this contact.
```
Expected behaviour
----------------------------------------
The data should be saved without error messages appearing (and this is what happens some of the time).
Environment information
----------------------------------------
* __Browser:__ Mostly tested on Chromium, most recently version 90.0.4430.93
* __CiviCRM:__ Tested on 5.33.5 and prior ESR versions
* __PHP:__ 7.3
* __CMS:__ Drupal 7.80
* __Database:__ 10.3.27-MariaDB
* __Web Server:__ Apache
Comments
----------------------------------------
We have mitigated the problem with this patch (minus the watchdog line with the FIXME comment):
https://github.com/AsylumSeekersCentre/civicrm-core/commit/030ecb6e31ed17b9fd01716cb772f13bb60bf455
With this in place, I've been unable to reproduce the error in manual testing. If it still happens, it's very rare. However, I'm not sure that this is a very "proper" solution so I'm opening the issue without a pull request for discussion.
The watchdog line from that patch usually produces output like this:
```
( ( `contact_a`.id IN ( SELECT contact_id FROM civicrm_group_contact WHERE group_id IN (5, 6) AND status = 'Added' ) ) ) AND (contact_a.is_deleted = 0)
```
On the occasions when the permission failure occurs, it instead looks like this:
```
( ( `contact_a`.id IN ( SELECT contact_id FROM civicrm_group_contact WHERE group_id IN (5) AND status = 'Added' ) ) ) AND (contact_a.is_deleted = 0)
```
It has somehow lost one of the groups it should be checking for. It always seems to retain the same one, which I think is why it works if the user is only affected by one ACL, and the bug only shows up if users are affected by multiple ACLs.https://lab.civicrm.org/dev/financial/-/issues/175Can't remove previously-added currencies2021-07-01T18:10:13Zmegaphonetech-dennisCan't remove previously-added currenciesOverview
----------------------------------------
When I remove previously-added currencies from the list of available currencies under *Language and Currency* and hit the **Save** button, the currencies are still listed among the avail...Overview
----------------------------------------
When I remove previously-added currencies from the list of available currencies under *Language and Currency* and hit the **Save** button, the currencies are still listed among the available currencies when I return to that page.
Reproduction steps
----------------------------------------
1. Go to **Administer** >> **Localization** >> **Languages, Currency, Locations**
1. Next to *Available Currencies* add some currencies. I used CLP and TWD. Click on the **Save** button located at the bottom of the page.
1. Return to **Administer** >> **Localization** >> **Languages, Currency, Locations**
1. Next to *Available Currencies* remove previously-added currencies, and click on the **Save** button located at the bottom of the page.
1. Return to **Administer** >> **Localization** >> **Languages, Currency, Locations** and find those currencies still listed next to *Available Currencies*.
Current behaviour
----------------------------------------
There are no error messages or any indication that something has gone wrong.
Expected behaviour
----------------------------------------
I expected the currencies I removed from this page to no longer be listed as *Available Currencies* when I returned to this page.
Environment information
----------------------------------------
Replicable on the demo server.https://lab.civicrm.org/dev/financial/-/issues/174Partial payment records amount of full contribution disrupting balance2023-06-16T09:36:40Zmagnolia61Partial payment records amount of full contribution disrupting balanceIn https://lab.civicrm.org/dev/financial/-/issues/173 the user dashboard pay now button was enabled for partially paid contributions. When I first tested this it looked fine, as the proper remaining amount was charged for the additional ...In https://lab.civicrm.org/dev/financial/-/issues/173 the user dashboard pay now button was enabled for partially paid contributions. When I first tested this it looked fine, as the proper remaining amount was charged for the additional payment.
On further testing I noticed that it was not recorded properly. Situation was like this:
Contribution Amount = 155
Initial payment = 55
Amount Due = 100
Via the User Dashboard Pay Now button the remaining 100 is paid.
The contribution status is now completed.
But the payment transaction is recorded as being the full 155.
So Civi thinks too much has been paid.
![Screenshot_2021-06-02_Dashboard_-_Testdeel_contribution_Gedeeltelijk_Stichting_Onvergetelijke_Zomerkampen](/uploads/aafe9f5a09dd4a57a4ad39042cf5148d/Screenshot_2021-06-02_Dashboard_-_Testdeel_contribution_Gedeeltelijk_Stichting_Onvergetelijke_Zomerkampen.png)
![Screenshot_2021-06-02_Online_betalen_Stichting_Onvergetelijke_Zomerkampen](/uploads/1905ada9754fb2414871da4197ec45c6/Screenshot_2021-06-02_Online_betalen_Stichting_Onvergetelijke_Zomerkampen.png)
![Screenshot_2021-06-02_Testdeel_contribution_Gedeeltelijk_Stichting_Onvergetelijke_Zomerkampen](/uploads/b5501ee9d40fd6ae41f1a1ae1692bf6c/Screenshot_2021-06-02_Testdeel_contribution_Gedeeltelijk_Stichting_Onvergetelijke_Zomerkampen.png)
The second payment should have been recorded as 100 euro, but is listed as the full contribution amount
![Screenshot_2021-06-02_Testdeel_contribution_Gedeeltelijk_Stichting_Onvergetelijke_Zomerkampen-balance](/uploads/9fbebc447f2cfe1b00dd6d4c9040fc33/Screenshot_2021-06-02_Testdeel_contribution_Gedeeltelijk_Stichting_Onvergetelijke_Zomerkampen-balance.png)https://lab.civicrm.org/dev/core/-/issues/2630Improve performance of queries in CRM_Contact_Form_Search_Custom_Base2023-02-06T04:12:42ZErikHommelImprove performance of queries in CRM_Contact_Form_Search_Custom_BaseSee this SE post: https://civicrm.stackexchange.com/questions/39636/slow-query-fixes-msp-custom-searches
It might be worth implementing the suggested improvements?See this SE post: https://civicrm.stackexchange.com/questions/39636/slow-query-fixes-msp-custom-searches
It might be worth implementing the suggested improvements?https://lab.civicrm.org/dev/user-interface/-/issues/37Selection in quick search result list is not visible2021-08-13T21:27:08Ztimo.kabschSelection in quick search result list is not visibleIn the result list of quick search, the contact to open can be selected by mouse or keyboard (cursor up/down). Previously, the selection of the to-be-opened contact was indicated by a rectangle outline around the contact.
Starting with 5...In the result list of quick search, the contact to open can be selected by mouse or keyboard (cursor up/down). Previously, the selection of the to-be-opened contact was indicated by a rectangle outline around the contact.
Starting with 5.37 or 5.37.1 (probably along the feature of results being "real" links) this selection is not visible anymore.
![QuickSearchResults](/uploads/f940354b2a96d88fae1c7a2757f4de00/QuickSearchResults.jpg)
Environment:
- dmaster on macOS with Safari Version 14.1 (16611.1.21.161.6) and on macOS and Win10 with Chrome Version 90.0.4430.212
- own installation with macOS with Safari Version 14.1 (16611.1.21.161.6)
Steps to reproduce:
1. open dmaster and login
1. in the quick search input field, enter 'd'
1. a search result list appears (Clint Adams, Kiara Adams, Toby Adams, ...)
1. press cursor down two times
1. press enter
What happens?
- when pressing cursor down, the search result list is walked through, but the current selection is not visible
- when pressing enter after two times pressing cursor down, contact 'Kiara Adams' is opened
- when hovering a result in the result list with mouse cursor, the current selection is not visible
What should happen?
- when pressing cursor down, the search result list is walked through, and the current selection is marked by a outline rectangle
- when hovering a result in the result list with mouse cursor, the hovered search result is marked by a outline rectangle5.41.0https://lab.civicrm.org/dev/core/-/issues/2597Tabset for manage contribution pages or manage events requires Classname to e...2023-08-07T15:13:57ZlarsssandergreenTabset for manage contribution pages or manage events requires Classname to equal pathIf you add a tab to a tabset for Configure Event, it will work fine with the last word of the class name different from the last word of the path, except for trying to save, which will save, but redirect to Manage Events instead of stayi...If you add a tab to a tabset for Configure Event, it will work fine with the last word of the class name different from the last word of the path, except for trying to save, which will save, but redirect to Manage Events instead of staying on the same tab. This is because [code here](https://github.com/civicrm/civicrm-core/blob/5db0bc3c1f54eaca4307f103a73bda596ae914d6/CRM/Event/Form/ManageEvent.php#L377) expects lastWord from CRM_myExtension_Form_lastWord to be the same as the path, i.e. /civicrm/event/manage/lastword. Everything else works as expected if these are different, except Save.
Looks like this same issue exists for [Contribution Pages](https://github.com/civicrm/civicrm-core/blob/5db0bc3c1f54eaca4307f103a73bda596ae914d6/CRM/Contribute/Form/ContributionPage.php#L427
) and probably elsewhere.
For now, I've added a warning to the docs for [the tabset hook](https://lab.civicrm.org/documentation/docs/dev/-/merge_requests/908). It would be good to fix this so the code linked above uses the path for the url instead of the class, at some point.https://lab.civicrm.org/dev/core/-/issues/2595Change Log Tab Excrutiatingly Slow - Poorly Performing Query and Fix (from 8 ...2023-08-14T13:09:44ZgordanChange Log Tab Excrutiatingly Slow - Poorly Performing Query and Fix (from 8 minutes down to 4 seconds)The page takes about 8 minutes to return which is absurdly slow for anything expected to be remotely interactive. It is so slow that my client is referring to it as the "Triangle of Doom".
I tracked it down to this query:
```
INSERT IG...The page takes about 8 minutes to return which is absurdly slow for anything expected to be remotely interactive. It is so slow that my client is referring to it as the "Triangle of Doom".
I tracked it down to this query:
```
INSERT IGNORE INTO civicrm_tmp_e_logsummary_ffa3ac146126d178ade367f2a5d17bf5
SELECT activity_id, IF (entity_log_civireport.log_action = 'Insert' AND extra_table.activity_type_id = 51 , GROUP_CONCAT(entity_log_civireport.contact_id), 1) , entity_log_civireport.log_action as log_civicrm_entity_log_action, 'log_civicrm_activity_contact' as log_civicrm_entity_log_type, entity_log_civireport.log_user_id as log_civicrm_entity_log_user_id, entity_log_civireport.log_date as log_civicrm_entity_log_date, modified_contact_civireport.display_name as log_civicrm_entity_altered_contact, modified_contact_civireport.id as log_civicrm_entity_altered_contact_id, entity_log_civireport.log_conn_id as log_civicrm_entity_log_conn_id, modified_contact_civireport.is_deleted as log_civicrm_entity_is_deleted, altered_by_contact_civireport.display_name as altered_by_contact_display_name
FROM staging_civicrm.log_civicrm_activity_contact entity_log_civireport
JOIN civicrm_contact modified_contact_civireport ON (entity_log_civireport.contact_id = modified_contact_civireport.id )
JOIN staging_civicrm.log_civicrm_activity extra_table ON extra_table.id = entity_log_civireport.activity_id
LEFT JOIN civicrm_contact altered_by_contact_civireport ON (entity_log_civireport.log_user_id = altered_by_contact_civireport.id)
WHERE modified_contact_civireport.id = 338520 AND
entity_log_civireport.log_action != 'Initialization'
GROUP BY entity_log_civireport.log_conn_id,
entity_log_civireport.log_user_id,
EXTRACT(DAY_MICROSECOND FROM entity_log_civireport.log_date),
entity_log_civireport.id
ORDER BY entity_log_civireport.log_date DESC;
EXPLAIN shows:
```
```
+------+-------------+-------------------------------+--------+---------------+---------+---------+---------------------------------------------------+---------+-------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------------------------------+--------+---------------+---------+---------+---------------------------------------------------+---------+-------------------------------------------------+
| 1 | SIMPLE | modified_contact_civireport | const | PRIMARY | PRIMARY | 4 | const | 1 | Using temporary; Using filesort |
| 1 | SIMPLE | extra_table | ALL | NULL | NULL | NULL | NULL | 3014020 | |
| 1 | SIMPLE | entity_log_civireport | ALL | NULL | NULL | NULL | NULL | 5518537 | Using where; Using join buffer (flat, BNL join) |
| 1 | SIMPLE | altered_by_contact_civireport | eq_ref | PRIMARY | PRIMARY | 4 | staging_civicrm.entity_log_civireport.log_user_id | 1 | Using where |
+------+-------------+-------------------------------+--------+---------------+---------+---------+---------------------------------------------------+---------+-------------------------------------------------+
```
The fix passes:
First pass:
```
ALTER TABLE log_civicrm_activity_contact ADD INDEX index_activity_id (activity_id);
```
With no further changes, this alone makes the above query go from 8 minutes to 1m45s.
Explain plain:
```
+------+-------------+-------------------------------+--------+-------------------+-------------------+---------+---------------------------------------------------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------------------------------+--------+-------------------+-------------------+---------+---------------------------------------------------+---------+---------------------------------+
| 1 | SIMPLE | modified_contact_civireport | const | PRIMARY | PRIMARY | 4 | const | 1 | Using temporary; Using filesort |
| 1 | SIMPLE | extra_table | ALL | NULL | NULL | NULL | NULL | 3014020 | Using where |
| 1 | SIMPLE | entity_log_civireport | ref | index_activity_id | index_activity_id | 5 | staging_civicrm.extra_table.id | 1 | Using where |
| 1 | SIMPLE | altered_by_contact_civireport | eq_ref | PRIMARY | PRIMARY | 4 | staging_civicrm.entity_log_civireport.log_user_id | 1 | Using where |
+------+-------------+-------------------------------+--------+-------------------+-------------------+---------+---------------------------------------------------+---------+---------------------------------+
```
Second pass:
```
ALTER TABLE log_civicrm_activity ADD INDEX index_id (id);
```
Change the JOIN order explicitly and add a hint for the query optimizer to not re-order the JOINs:
```
SELECT STRAIGHT_JOIN activity_id, IF (entity_log_civireport.log_action = 'Insert' AND extra_table.activity_type_id = 51 , GROUP_CONCAT(entity_log_civireport.contact_id), 1) , entity_log_civireport.log_action as log_civicrm_entity_log_action, 'log_civicrm_activity_contact' as log_civicrm_entity_log_type, entity_log_civireport.log_user_id as log_civicrm_entity_log_user_id, entity_log_civireport.log_date as log_civicrm_entity_log_date, modified_contact_civireport.display_name as log_civicrm_entity_altered_contact, modified_contact_civireport.id as log_civicrm_entity_altered_contact_id, entity_log_civireport.log_conn_id as log_civicrm_entity_log_conn_id, modified_contact_civireport.is_deleted as log_civicrm_entity_is_deleted, altered_by_contact_civireport.display_name as altered_by_contact_display_name
FROM civicrm_contact modified_contact_civireport
JOIN staging_civicrm.log_civicrm_activity_contact entity_log_civireport ON entity_log_civireport.contact_id = modified_contact_civireport.id
JOIN staging_civicrm.log_civicrm_activity extra_table ON extra_table.id = entity_log_civireport.activity_id
LEFT JOIN civicrm_contact altered_by_contact_civireport ON entity_log_civireport.log_user_id = altered_by_contact_civireport.id
WHERE modified_contact_civireport.id = 338520 AND
entity_log_civireport.log_action != 'Initialization'
GROUP BY entity_log_civireport.log_conn_id,
entity_log_civireport.log_user_id,
EXTRACT(DAY_MICROSECOND FROM entity_log_civireport.log_date),
entity_log_civireport.id
ORDER BY entity_log_civireport.log_date DESC;
```
New EXPLAIN:
```
+------+-------------+-------------------------------+--------+-------------------+----------+---------+---------------------------------------------------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------------------------------+--------+-------------------+----------+---------+---------------------------------------------------+---------+---------------------------------+
| 1 | SIMPLE | modified_contact_civireport | const | PRIMARY | PRIMARY | 4 | const | 1 | Using temporary; Using filesort |
| 1 | SIMPLE | entity_log_civireport | ALL | index_activity_id | NULL | NULL | NULL | 5518537 | Using where; Using filesort |
| 1 | SIMPLE | extra_table | ref | index_id | index_id | 5 | staging_civicrm.entity_log_civireport.activity_id | 1 | |
| 1 | SIMPLE | altered_by_contact_civireport | eq_ref | PRIMARY | PRIMARY | 4 | staging_civicrm.entity_log_civireport.log_user_id | 1 | Using where |
+------+-------------+-------------------------------+--------+-------------------+----------+---------+---------------------------------------------------+---------+---------------------------------+
```
This gets it down to 4 seconds!
Since the first index we started with is no longer getting used in the final variant, we can just not add it.
Summary:
To fix "Change Log" tab taking forever to load, the following fix is needed:
Add index:
```
ALTER TABLE log_civicrm_activity ADD INDEX index_id (id);
```
Make the code emit the query modified as follows:
```
INSERT IGNORE INTO civicrm_tmp_e_logsummary_ffa3ac146126d178ade367f2a5d17bf5
SELECT STRAIGHT_JOIN activity_id, IF (entity_log_civireport.log_action = 'Insert' AND extra_table.activity_type_id = 51 , GROUP_CONCAT(entity_log_civireport.contact_id), 1) , entity_log_civireport.log_action as log_civicrm_entity_log_action, 'log_civicrm_activity_contact' as log_civicrm_entity_log_type, entity_log_civireport.log_user_id as log_civicrm_entity_log_user_id, entity_log_civireport.log_date as log_civicrm_entity_log_date, modified_contact_civireport.display_name as log_civicrm_entity_altered_contact, modified_contact_civireport.id as log_civicrm_entity_altered_contact_id, entity_log_civireport.log_conn_id as log_civicrm_entity_log_conn_id, modified_contact_civireport.is_deleted as log_civicrm_entity_is_deleted, altered_by_contact_civireport.display_name as altered_by_contact_display_name
FROM civicrm_contact modified_contact_civireport
JOIN staging_civicrm.log_civicrm_activity_contact entity_log_civireport ON entity_log_civireport.contact_id = modified_contact_civireport.id
JOIN staging_civicrm.log_civicrm_activity extra_table ON extra_table.id = entity_log_civireport.activity_id
LEFT JOIN civicrm_contact altered_by_contact_civireport ON entity_log_civireport.log_user_id = altered_by_contact_civireport.id
WHERE modified_contact_civireport.id = 338520 AND
entity_log_civireport.log_action != 'Initialization'
GROUP BY entity_log_civireport.log_conn_id,
entity_log_civireport.log_user_id,
EXTRACT(DAY_MICROSECOND FROM entity_log_civireport.log_date),
entity_log_civireport.id
ORDER BY entity_log_civireport.log_date DESC;
```
Not only does this speed it up from 8 minutes down to 4 seconds, it also doesn't wreak havoc with row locking where every row scanned gets locked by the transaction engine, potentially resulting in a massive query pile-up in the database.