/library/ZFDoctrine/Application/Resource/Doctrine.php

https://github.com/leadhome/handmade · PHP · 345 lines · 199 code · 60 blank · 86 comment · 30 complexity · 2ad050a6b550ad24549be288230101cc MD5 · raw file

  1. <?php
  2. /**
  3. * ZFDoctrine
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * If you did not receive a copy of the license and are unable to
  10. * obtain it through the world-wide-web, please send an email
  11. * to kontakt@beberlei.de so I can send you a copy immediately.
  12. */
  13. class ZFDoctrine_Application_Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract
  14. {
  15. /**
  16. * @var array
  17. */
  18. protected $_paths = array();
  19. /**
  20. * @var array
  21. */
  22. protected $_managerOptions = array();
  23. /**
  24. * @var array
  25. */
  26. protected $_connectionOptions = array();
  27. /**
  28. * @var array
  29. */
  30. protected $_generateModelOptions = array();
  31. /**
  32. * Build DSN string from an array
  33. *
  34. * @param array $dsn
  35. * @return string
  36. */
  37. protected function _buildDsnFromArray(array $dsn)
  38. {
  39. $options = null;
  40. if (array_key_exists('options', $dsn)) {
  41. $options = http_build_query($dsn['options']);
  42. }
  43. return sprintf('%s://%s:%s@%s/%s?%s',
  44. $dsn['adapter'],
  45. $dsn['user'],
  46. $dsn['pass'],
  47. $dsn['hostspec'],
  48. $dsn['database'],
  49. $options);
  50. }
  51. /**
  52. * Set attributes for a Doctrine_Configurable instance
  53. *
  54. * @param Doctrine_Configurable $object
  55. * @param array $attributes
  56. * @return void
  57. * @throws Zend_Application_Resource_Exception
  58. */
  59. protected function _setAttributes(Doctrine_Configurable $object, array $attributes)
  60. {
  61. $reflect = new ReflectionClass('ZFDoctrine_Core');
  62. $doctrineConstants = $reflect->getConstants();
  63. $attributes = array_change_key_case($attributes, CASE_UPPER);
  64. foreach ($attributes as $key => $value) {
  65. if (!array_key_exists($key, $doctrineConstants)) {
  66. throw new Zend_Application_Resource_Exception("Invalid attribute $key.");
  67. }
  68. $attrIdx = $doctrineConstants[$key];
  69. $attrVal = $value;
  70. if (Doctrine_Core::ATTR_QUERY_CACHE == $attrIdx) {
  71. $attrVal = $this->_getCache($value);
  72. } elseif (Doctrine_Core::ATTR_RESULT_CACHE == $attrIdx) {
  73. $attrVal = $this->_getCache($value);
  74. } else {
  75. if (is_string($value)) {
  76. $value = strtoupper($value);
  77. if (array_key_exists($value, $doctrineConstants)) {
  78. $attrVal = $doctrineConstants[$value];
  79. }
  80. }
  81. }
  82. $object->setAttribute($attrIdx, $attrVal);
  83. }
  84. }
  85. /**
  86. * Set connection listeners
  87. *
  88. * @param Doctrine_Connection_Common $conn
  89. * @param array $options
  90. * @return void
  91. * @throws Zend_Application_Resource_Exception
  92. */
  93. protected function _setConnectionListeners(Doctrine_Connection_Common $conn, array $options)
  94. {
  95. foreach ($options as $alias => $class) {
  96. if (!class_exists($class)) {
  97. throw new Zend_Application_Resource_Exception("$class does not exist.");
  98. }
  99. $conn->addListener(new $class(), $alias);
  100. }
  101. }
  102. /**
  103. * Retrieve a Doctrine_Cache instance
  104. *
  105. * @param array $options
  106. * @return Doctrine_Cache
  107. * @throws Zend_Application_Resource_Exception
  108. */
  109. protected function _getCache(array $options)
  110. {
  111. if (!array_key_exists('driver', $options)) {
  112. throw new Zend_Application_Resource_Exception('Undefined cache driver.');
  113. }
  114. switch ($options['driver'])
  115. {
  116. case 'apc':
  117. return new Doctrine_Cache_Apc();
  118. case 'db':
  119. if (!array_key_exists('options', $options)) {
  120. throw new Zend_Application_Resource_Exception('Undefined db cache options.');
  121. }
  122. if (empty($options['options'])) {
  123. throw new Zend_Application_Resource_Exception('Invalid db cache options.');
  124. }
  125. if (!array_key_exists('dsn', $options['options'])) {
  126. throw new Zend_Application_Resource_Exception("Undefined db cache DSN.");
  127. }
  128. if (empty($options['options']['dsn'])) {
  129. throw new Zend_Application_Resource_Exception("Invalid db cache DSN.");
  130. }
  131. if (!array_key_exists('tableName', $options['options'])) {
  132. throw new Zend_Application_Resource_Exception("Undefined db cache table name.");
  133. }
  134. if (empty($options['options']['tableName'])) {
  135. throw new Zend_Application_Resource_Exception("Invalid db cache table name.");
  136. }
  137. $dsn = (is_array($options['options']['dsn']))
  138. ? $this->_buildDsnFromArray($options['options']['dsn'])
  139. : $options['options']['dsn'];
  140. $cacheConn = Doctrine_Manager::connection($dsn);
  141. $cache = new Doctrine_Cache_Db(array(
  142. 'connection' => $cacheConn,
  143. 'tableName' => $options['options']['tableName'],
  144. ));
  145. return $cache;
  146. case 'memcache':
  147. if (!array_key_exists('options', $options)) {
  148. throw new Zend_Application_Resource_Exception('Undefined memcache options.');
  149. }
  150. if (empty($options['options'])) {
  151. throw new Zend_Application_Resource_Exception('Invalid memcache options.');
  152. }
  153. $driver = new Doctrine_Cache_Memcache($options['options']);
  154. Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_QUERY_CACHE, $driver);
  155. Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_RESULT_CACHE, $driver);
  156. return $driver;
  157. case 'xcache':
  158. return new Doctrine_Cache_Xcache();
  159. default:
  160. throw new Zend_Application_Resource_Exception('Unsupported cache driver.');
  161. }
  162. }
  163. /**
  164. * Set manager level attributes
  165. *
  166. * @param array $options
  167. * @return ZFDoctrine_Application_Resource_Doctrine
  168. */
  169. public function setManager(array $options)
  170. {
  171. $this->_managerOptions = array_change_key_case($options, CASE_LOWER);
  172. }
  173. /**
  174. * Set connections and connection level attributes
  175. *
  176. * @param array $options
  177. * @return ZFDoctrine_Application_Resource_Doctrine
  178. * @throws Zend_Application_Resource_Exception
  179. */
  180. public function setConnections(array $options)
  181. {
  182. $options = array_change_key_case($options, CASE_LOWER);
  183. $this->_connectionOptions = $options;
  184. return $this;
  185. }
  186. public function setGenerateModels(array $options)
  187. {
  188. $this->_generateModelOptions = $options;
  189. return $this;
  190. }
  191. protected function _initConnections()
  192. {
  193. $connections = array();
  194. foreach($this->_connectionOptions as $key => $value) {
  195. if (!is_array($value)) {
  196. throw new Zend_Application_Resource_Exception("Invalid connection on $key.");
  197. }
  198. if (!array_key_exists('dsn', $value)) {
  199. throw new Zend_Application_Resource_Exception("Undefined DSN on $key.");
  200. }
  201. if (empty($value['dsn'])) {
  202. throw new Zend_Application_Resource_Exception("Invalid DSN on $key.");
  203. }
  204. $dsn = (is_array($value['dsn']))
  205. ? $this->_buildDsnFromArray($value['dsn'])
  206. : $value['dsn'];
  207. $conn = Doctrine_Manager::connection($dsn, $key);
  208. if (array_key_exists('charset', $value)) {
  209. $conn->setCharset($value['charset']);
  210. }
  211. if (array_key_exists('attributes', $value)) {
  212. $this->_setAttributes($conn, $value['attributes']);
  213. }
  214. if (array_key_exists('listeners', $value)) {
  215. $this->_setConnectionListeners($conn, $value['listeners']);
  216. }
  217. $connections[$key] = $conn;
  218. }
  219. return $connections;
  220. }
  221. /**
  222. * @return Doctrine_Manager
  223. */
  224. protected function _initManager()
  225. {
  226. $manager = Doctrine_Manager::getInstance();
  227. $manager->setAttribute(Doctrine_Core::ATTR_MODEL_LOADING, ZFDoctrine_Core::MODEL_LOADING_ZEND); // default
  228. if (array_key_exists('attributes', $this->_managerOptions)) {
  229. $this->_setAttributes($manager, $this->_managerOptions['attributes']);
  230. }
  231. return $manager;
  232. }
  233. /**
  234. * Initialize Doctrine paths
  235. *
  236. * @param array $options
  237. * @return ZFDoctrine_Application_Resource_Doctrine
  238. * @throws Zend_Application_Resource_Exception
  239. */
  240. protected function setPaths(array $options)
  241. {
  242. $options = array_change_key_case($options, CASE_LOWER);
  243. foreach ($options as $key => $value) {
  244. if (!is_array($value)) {
  245. throw new Zend_Application_Resource_Exception("Invalid paths on $key.");
  246. }
  247. $this->_paths[$key] = array();
  248. foreach ($value as $subKey => $subVal) {
  249. if (!empty($subVal)) {
  250. $path = realpath($subVal);
  251. if (!is_dir($path)) {
  252. throw new Zend_Application_Resource_Exception("$subVal does not exist.");
  253. }
  254. $this->_paths[$key][$subKey] = $path;
  255. }
  256. }
  257. }
  258. return $this;
  259. }
  260. /**
  261. * Retrieve paths
  262. *
  263. * @return array
  264. */
  265. public function getPaths()
  266. {
  267. return $this->_paths;
  268. }
  269. /**
  270. * Defined by Zend_Application_Resource_Resource
  271. *
  272. * @return ZFDoctrine_Application_Resource_Doctrine
  273. * @throws Zend_Application_Resource_Exception
  274. */
  275. public function init()
  276. {
  277. if (!class_exists('Doctrine_Core')) {
  278. throw ZFDoctrine_DoctrineException::doctrineNotFound();
  279. }
  280. spl_autoload_register(array('Doctrine_Core', 'autoload'));
  281. $manager = $this->_initManager();
  282. $connections = $this->_initConnections();
  283. return new ZFDoctrine_Registry($manager, $connections, $this->_paths, $this->_generateModelOptions);
  284. }
  285. }