1: <?php
  2: 
  3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25: 
 26: uses ('model' . DS . 'datasources' . DS . 'datasource');
 27: config('database');
 28: 
 29:  30:  31:  32:  33:  34:  35:  36: 
 37: class ConnectionManager extends Object {
 38:  39:  40:  41:  42:  43: 
 44:     var $config = null;
 45:  46:  47:  48:  49:  50: 
 51:     var $_dataSources = array();
 52:  53:  54:  55:  56:  57: 
 58:     var $_connectionsEnum = array();
 59:  60:  61:  62: 
 63:     function __construct() {
 64:         if (class_exists('DATABASE_CONFIG')) {
 65:             $this->config =& new DATABASE_CONFIG();
 66:         }
 67:     }
 68:  69:  70:  71:  72:  73:  74: 
 75:     function &getInstance() {
 76:         static $instance = array();
 77: 
 78:         if (!$instance) {
 79:             $instance[0] =& new ConnectionManager();
 80:         }
 81: 
 82:         return $instance[0];
 83:     }
 84:  85:  86:  87:  88:  89:  90:  91: 
 92:     function &getDataSource($name) {
 93:         $_this =& ConnectionManager::getInstance();
 94: 
 95:         if (!empty($_this->_dataSources[$name])) {
 96:             $return =& $_this->_dataSources[$name];
 97:             return $return;
 98:         }
 99: 
100:         $connections = $_this->enumConnectionObjects();
101:         if (!empty($connections[$name])) {
102:             $conn = $connections[$name];
103:             $class = $conn['classname'];
104:             $_this->loadDataSource($name);
105:             $_this->_dataSources[$name] =& new $class($_this->config->{$name});
106:             $_this->_dataSources[$name]->configKeyName = $name;
107:         } else {
108:             trigger_error(sprintf(__("ConnectionManager::getDataSource - Non-existent data source %s", true), $name), E_USER_ERROR);
109:             return null;
110:         }
111: 
112:         $return =& $_this->_dataSources[$name];
113:         return $return;
114:     }
115: 116: 117: 118: 119: 120: 121: 
122:     function sourceList() {
123:         $_this =& ConnectionManager::getInstance();
124:         return array_keys($_this->_dataSources);
125:     }
126: 127: 128: 129: 130: 131: 132: 133: 
134:     function getSourceName(&$source) {
135:         $_this =& ConnectionManager::getInstance();
136:         $names = array_keys($_this->_dataSources);
137:         for ($i = 0, $count = count($names); $i < $count; $i++) {
138:             if ($_this->_dataSources[$names[$i]] === $source) {
139:                 return $names[$i];
140:             }
141:         }
142:         return null;
143:     }
144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 
154:     function loadDataSource($connName) {
155:         $_this =& ConnectionManager::getInstance();
156: 
157:         if (is_array($connName)) {
158:             $conn = $connName;
159:         } else {
160:             $connections = $_this->enumConnectionObjects();
161:             $conn = $connections[$connName];
162:         }
163: 
164:         if (!empty($conn['parent'])) {
165:             $_this->loadDataSource($conn['parent']);
166:         }
167: 
168:         if (class_exists($conn['classname'])) {
169:             return false;
170:         }
171: 
172:         if (file_exists(MODELS . 'datasources' . DS . $conn['filename'] . '.php')) {
173:             require (MODELS . 'datasources' . DS . $conn['filename'] . '.php');
174:         } elseif (fileExistsInPath(LIBS . 'model' . DS . 'datasources' . DS . $conn['filename'] . '.php')) {
175:             require (LIBS . 'model' . DS . 'datasources' . DS . $conn['filename'] . '.php');
176:         } else {
177:             $error = __('Unable to load DataSource file %s.php', true);
178:             trigger_error(sprintf($error, $conn['filename']), E_USER_ERROR);
179:             return null;
180:         }
181: 
182:         return true;
183:     }
184: 185: 186: 187: 188: 189: 190: 191: 
192:     function enumConnectionObjects() {
193:         $_this =& ConnectionManager::getInstance();
194: 
195:         if (!empty($_this->_connectionsEnum)) {
196:             return $_this->_connectionsEnum;
197:         }
198:         $connections = get_object_vars($_this->config);
199: 
200:         if ($connections != null) {
201:             foreach ($connections as $name => $config) {
202:                 $_this->_connectionsEnum[$name] = $_this->__getDriver($config);
203:             }
204:             return $_this->_connectionsEnum;
205:         } else {
206:             $_this->cakeError('missingConnection', array(array('className' => 'ConnectionManager')));
207:         }
208:     }
209: 210: 211: 212: 213: 214: 215: 216: 217: 
218:     function &create($name = '', $config = array()) {
219:         $_this =& ConnectionManager::getInstance();
220: 
221:         if (empty($name) || empty($config) || array_key_exists($name, $_this->_connectionsEnum)) {
222:             $null = null;
223:             return $null;
224:         }
225: 
226:         $_this->config->{$name} = $config;
227:         $_this->_connectionsEnum[$name] = $_this->__getDriver($config);
228:         $return =& $_this->getDataSource($name);
229:         return $return;
230:     }
231: 232: 233: 234: 235: 236: 
237:     function __getDriver($config) {
238:         if (!isset($config['datasource'])) {
239:             $config['datasource'] = 'dbo';
240:         }
241: 
242:         if (isset($config['driver']) && $config['driver'] != null && !empty($config['driver'])) {
243:             $filename = $config['datasource'] . DS . $config['datasource'] . '_' . $config['driver'];
244:             $classname = Inflector::camelize(strtolower($config['datasource'] . '_' . $config['driver']));
245:             $parent = $this->__getDriver(array('datasource' => $config['datasource']));
246:         } else {
247:             $filename = $config['datasource'] . '_source';
248:             $classname = Inflector::camelize(strtolower($config['datasource'] . '_source'));
249:             $parent = null;
250:         }
251:         return array('filename'  => $filename, 'classname' => $classname, 'parent' => $parent);
252:     }
253: 254: 255: 256: 257: 
258:     function __destruct() {
259:         if (Configure::read('Session.save') == 'database' && function_exists('session_write_close')) {
260:             session_write_close();
261:         }
262:     }
263: }
264: ?>