CRM-16373 - SettingsBag - Add getUrl/getPath/setUrl/setPath
authorTim Otten <totten@civicrm.org>
Sun, 23 Aug 2015 09:43:12 +0000 (02:43 -0700)
committerTim Otten <totten@civicrm.org>
Thu, 17 Sep 2015 22:45:01 +0000 (15:45 -0700)
Civi/Core/SettingsBag.php
tests/phpunit/Civi/Core/SettingsManagerTest.php

index 55a696ce44a058ec75d64aa529abb2c37b7a1b9a..f7c668b83944b375540509aacc827272dffe948d 100644 (file)
@@ -80,6 +80,8 @@ class SettingsBag {
    */
   protected $values;
 
+  protected $filteredValues;
+
   /**
    * @param int $domainId
    *   The domain for which we want settings.
@@ -108,7 +110,7 @@ class SettingsBag {
     $dao = $this->createDao();
     $dao->find();
     while ($dao->fetch()) {
-      $this->values[$dao->name] = is_string($dao->value) ? unserialize($dao->value) : NULL;
+      $this->values[$dao->name] = ($dao->value !== NULL) ? unserialize($dao->value) : NULL;
     }
     $this->combined = NULL;
     return $this;
@@ -154,6 +156,42 @@ class SettingsBag {
     return isset($all[$key]) ? $all[$key] : NULL;
   }
 
+  /**
+   * Get the value of a setting, formatted as a path.
+   *
+   * @param string $key
+   * @return string|NULL
+   *   Absolute path.
+   */
+  public function getPath($key) {
+    if (!isset($this->filteredValues[$key])) {
+      $this->filteredValues[$key] = \CRM_Utils_File::absoluteDirectory($this->get($key));
+    }
+    return $this->filteredValues[$key];
+  }
+
+  /**
+   * Get the value of a setting, formatted as a URL.
+   *
+   * @param string $key
+   * @param bool $preferFormat
+   *   The preferred format ('absolute', 'relative').
+   *   The result data may not meet the preference -- if the setting
+   *   refers to an external domain, then the result will be
+   *   absolute (regardless of preference).
+   * @parma bool|NULL $ssl
+   *   NULL to autodetect. TRUE to force to SSL.
+   * @return string|NULL
+   *   URL.
+   */
+  public function getUrl($key, $preferFormat, $ssl = NULL) {
+    if (!isset($this->filteredValues[$key][$preferFormat][$ssl])) {
+      $value = $this->filterUrl($this->get($key), $preferFormat, $ssl);
+      $this->filteredValues[$key][$preferFormat][$ssl] = $value;
+    }
+    return $this->filteredValues[$key][$preferFormat][$ssl];
+  }
+
   /**
    * Determine the explicitly designated value, regardless of
    * any default or mandatory values.
@@ -201,10 +239,33 @@ class SettingsBag {
   public function set($key, $value) {
     $this->setDb($key, $value);
     $this->values[$key] = $value;
+    unset($this->filteredValues[$key]);
     $this->combined = NULL;
     return $this;
   }
 
+  /**
+   * @param string $key
+   * @param string $value
+   *   Absolute path.
+   * @return $this
+   */
+  public function setPath($key, $value) {
+    $this->set($key, \CRM_Utils_File::relativeDirectory($value));
+    return $this;
+  }
+
+  /**
+   * @param string $key
+   * @param string $value
+   *   Absolute URL.
+   * @return $this
+   */
+  public function setUrl($key, $value) {
+    $this->set($key, \CRM_Utils_System::relativeURL($value));
+    return $this;
+  }
+
   /**
    * @return \CRM_Core_DAO_Setting
    */
@@ -267,4 +328,33 @@ class SettingsBag {
     //}
   }
 
+  /**
+   * Filter a URL, the same way that it would be if it were read from settings.
+   *
+   * @param $value
+   * @param $preferFormat
+   * @param $ssl
+   * @return mixed|string
+   */
+  public function filterUrl($value, $preferFormat, $ssl = NULL) {
+    if ($value) {
+      $value = \CRM_Utils_System::absoluteURL($value, TRUE);
+    }
+    if ($preferFormat === 'relative' && $value) {
+      $parsed = parse_url($value);
+      if (isset($_SERVER['HTTP_HOST']) && isset($parsed['host']) && $_SERVER['HTTP_HOST'] == $parsed['host']) {
+        $value = $parsed['path'];
+      }
+    }
+
+    if ($value) {
+      if ($ssl || ($ssl === NULL && \CRM_Utils_System::isSSL())) {
+        $value = str_replace('http://', 'https://', $value);
+        return $value;
+      }
+      return $value;
+    }
+    return $value;
+  }
+
 }
index 60263f3fd325e516b0d978175972075d79637b66..a3b09f27abb5e79645428a6ee44ee201b5ce78ea 100644 (file)
@@ -17,6 +17,10 @@ class SettingsManagerTest extends \CiviUnitTestCase {
       'd1' => 'alpha',
       'd2' => 'beta',
       'd3' => 'gamma',
+      'myrelpath' => 'foo',
+      'myabspath' => '/tmp/bar',
+      'myrelurl' => 'sites/foo',
+      'myabsurl' => 'http://example.com/bar',
     );
     $this->contactDefaults = array(
       'c1' => 'alpha',
@@ -117,6 +121,44 @@ class SettingsManagerTest extends \CiviUnitTestCase {
     $this->assertEquals('from contact', $contactSettings->get('monkeywrench'));
   }
 
+  public function testPaths() {
+    $domain = \CRM_Core_DAO::createTestObject('CRM_Core_DAO_Domain');
+    $manager = $this->createManager();
+    $settings = $manager->getBagByDomain($domain->id);
+
+    $this->assertEquals('foo', $settings->get('myrelpath'));
+    $this->assertRegExp(':/.+/foo$:', $settings->getPath('myrelpath'));
+    $settings->setPath('myrelpath', 'foo/sub');
+    $this->assertEquals('foo/sub', $settings->get('myrelpath'));
+    $this->assertRegExp(':/.+/foo/sub$:', $settings->getPath('myrelpath'));
+
+    $this->assertEquals('/tmp/bar', $settings->get('myabspath'));
+    $this->assertEquals('/tmp/bar', $settings->getPath('myabspath'));
+    $settings->setPath('myabspath', '/tmp/bar/whiz');
+    $this->assertEquals('/tmp/bar/whiz', $settings->get('myabspath'));
+  }
+
+  public function testUrl() {
+    $domain = \CRM_Core_DAO::createTestObject('CRM_Core_DAO_Domain');
+    $manager = $this->createManager();
+    $settings = $manager->getBagByDomain($domain->id);
+
+    $this->assertEquals('sites/foo', $settings->get('myrelurl'));
+    $this->assertRegExp(';^http.*sites/foo$;', $settings->getUrl('myrelurl', 'absolute'));
+    $this->assertRegExp(';^https:.*sites/foo$;', $settings->getUrl('myrelurl', 'absolute', TRUE));
+    //$this->assertEquals('/sites/foo', $settings->getUrl('myrelurl', 'relative'));
+    $settings->setUrl('myrelurl', 'sites/foo/sub');
+    $this->assertEquals('sites/foo/sub', $settings->get('myrelurl'));
+    $this->assertRegExp(';^http.*sites/foo/sub$;', $settings->getUrl('myrelurl', 'absolute'));
+    //$this->assertEquals('/sites/foo/sub', $settings->getUrl('myrelurl', 'relative'));
+
+    $this->assertEquals('http://example.com/bar', $settings->get('myabsurl'));
+    $this->assertEquals('http://example.com/bar', $settings->getUrl('myabsurl', 'absolute'));
+    $settings->setUrl('myabsurl', 'http://example.com/whiz');
+    $this->assertEquals('http://example.com/whiz', $settings->get('myabsurl'));
+    $this->assertEquals('http://example.com/whiz', $settings->getUrl('myabsurl', 'absolute'));
+  }
+
   /**
    * @return SettingsManager
    */