Browse Source

Add DSN parsing to StaticConfigTrait

Jose Diaz-Gonzalez 11 years ago
parent
commit
2ee6448a32
1 changed files with 66 additions and 1 deletions
  1. 66 1
      src/Core/StaticConfigTrait.php

+ 66 - 1
src/Core/StaticConfigTrait.php

@@ -81,7 +81,13 @@ trait StaticConfigTrait {
 		if (isset(static::$_config[$key])) {
 			throw new BadMethodCallException(sprintf('Cannot reconfigure existing key "%s"', $key));
 		}
-		if (is_object($config)) {
+		if (is_array($config)) {
+			$config = static::parseDsn($config);
+		} elseif ($config === null && is_array($key)) {
+			foreach ($key as $name => $settings) {
+				$key[$name] = static::parseDsn($settings);
+			}
+		} elseif (is_object($config)) {
 			$config = ['className' => $config];
 		}
 		if (isset($config['engine']) && empty($config['className'])) {
@@ -123,4 +129,63 @@ trait StaticConfigTrait {
 		return array_keys(static::$_config);
 	}
 
+/**
+ * Parses a dsn into a valid connection configuration
+ *
+ * This method allows setting a dsn using PEAR::DB formatting, with added support for drivers
+ * in the SQLAlchemy format. The following is an example of it's usage:
+ *
+ * {{{
+ * 	 $dsn = 'mysql+Cake\Database\Driver\Mysql://user:password@localhost:3306/database_name';
+ * 	 $config = ConnectionManager::parseDsn($dsn);
+ * }}
+ *
+ * If an array is given, the parsed dsn will be merged into this array. Note that querystring
+ * arguments are also parsed and set as values in the returned configuration.
+ *
+ * @param array $key An array with a `dsn` key mapping to a string dsn
+ * @return mixed null when adding configuration and an array of configuration data when reading.
+ */
+	public static function parseDsn($config) {
+		if (!is_array($config) || !isset($config['dsn'])) {
+			return $config;
+		}
+
+		$driver = null;
+		$dsn = $config['dsn'];
+		unset($config['dsn']);
+
+		if (preg_match("/^([\w]+)\+([\w\\\]+)/", $dsn, $matches)) {
+			$scheme = $matches[1];
+			$driver = $matches[2];
+			$dsn = preg_replace("/^([\w]+)\+([\w\\\]+)/", $scheme, $dsn);
+		}
+
+		$parsed = parse_url($dsn);
+		$query = '';
+
+		if (isset($parsed['query'])) {
+			$query = $parsed['query'];
+			unset($parsed['query']);
+		}
+
+		parse_str($query, $queryArgs);
+
+		if ($driver !== null) {
+			$queryArgs['driver'] = $driver;
+		}
+
+		$config = array_merge($queryArgs, $parsed, $config);
+
+		foreach ($config as $key => $value) {
+			if ($value === 'true') {
+				$config[$key] = true;
+			} elseif ($value === 'false') {
+				$config[$key] = false;
+			}
+		}
+
+		return $config;
+	}
+
 }