From 38e5457ebd3b37e96ee99d5afd3e49634ab3e135 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Sat, 16 Dec 2017 13:26:09 -0700 Subject: [PATCH] CRM-21568 - Move emptiness judgments from SettingsBag::setDb to InnoDBIndexer The `SettingsBag::setDb()` function calls any `on_change` listeners. It originally used "dumb on change" behavior (where it calls the listeners without comparing values). CRM-19610 had an issue where the `InnoDBIndexer` was running a bit too often, so they tried to resolve it by making the `SettingsBag::setDb()` more clever. Unfortunately, that's been a bit bouncy, and the cleverness depends on one's particular interpretation of 0 vs '0' vs '' vs NULL vs FALSE. Before ------ All on-change listeners may be skipped if there's particular mix of emptiness in the old/new values. After ----- The on-change listeners always fire. However, the specific listener involved with CRM-19610 will now ignore some insignificant changes. Related discussion: https://github.com/civicrm/civicrm-core/pull/11417 ---------------------------------------- * CRM-21568: https://issues.civicrm.org/jira/browse/CRM-21568 * CRM-19610: https://issues.civicrm.org/jira/browse/CRM-19610 --- CRM/Core/InnoDBIndexer.php | 4 ++++ Civi/Core/SettingsBag.php | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CRM/Core/InnoDBIndexer.php b/CRM/Core/InnoDBIndexer.php index 5c2c8fb44d..6d7ae283d4 100644 --- a/CRM/Core/InnoDBIndexer.php +++ b/CRM/Core/InnoDBIndexer.php @@ -91,6 +91,10 @@ class CRM_Core_InnoDBIndexer { * Specification of the setting (per *.settings.php). */ public static function onToggleFts($oldValue, $newValue, $metadata) { + if (empty($oldValue) && empty($newValue)) { + return; + } + $indexer = CRM_Core_InnoDBIndexer::singleton(); $indexer->setActive($newValue); $indexer->fixSchemaDifferences(); diff --git a/Civi/Core/SettingsBag.php b/Civi/Core/SettingsBag.php index 2aee1eb1c2..66a663e93b 100644 --- a/Civi/Core/SettingsBag.php +++ b/Civi/Core/SettingsBag.php @@ -352,9 +352,11 @@ class SettingsBag { } $dao->find(TRUE); - // string comparison with 0 always return true, so to be ensure the type use === - // ref - https://stackoverflow.com/questions/8671942/php-string-comparasion-to-0-integer-returns-true - if (isset($metadata['on_change']) && !($value === 0 && ($dao->value === NULL || unserialize($dao->value) == 0))) { + // Call 'on_change' listeners. It would be nice to only fire when there's + // a genuine change in the data. However, PHP developers have mixed + // expectations about whether 0, '0', '', NULL, and FALSE represent the same + // value, so there's no universal way to determine if a change is genuine. + if (isset($metadata['on_change'])) { foreach ($metadata['on_change'] as $callback) { call_user_func( \Civi\Core\Resolver::singleton()->get($callback), -- 2.25.1