CRM-21568 - Move emptiness judgments from SettingsBag::setDb to InnoDBIndexer
authorTim Otten <totten@civicrm.org>
Sat, 16 Dec 2017 20:26:09 +0000 (13:26 -0700)
committerTim Otten <totten@civicrm.org>
Sat, 16 Dec 2017 20:49:43 +0000 (13:49 -0700)
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
Civi/Core/SettingsBag.php

index 5c2c8fb44d201fa5c7354b8c1849dfd78276c5c0..6d7ae283d4b84f9db76df5b4e47a927b9550ef37 100644 (file)
@@ -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();
index 2aee1eb1c205b2bf799e1f256dc67e9654f564f9..66a663e93bad56665d78bfdf46f5fd6b42b3759f 100644 (file)
@@ -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),