PageRenderTime 25ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Core/Model/Resource/Abstract.php

https://github.com/hettema/Stages
PHP | 325 lines | 155 code | 35 blank | 135 comment | 31 complexity | fd61ba0d77056715dd8d147ca0720407 MD5 | raw file
  1. <?php
  2. /**
  3. * class Core_Model_Resource_Abstract
  4. * Abstract class for Resource model handling the database operations
  5. *
  6. * @package Core
  7. * @subpackage Resource
  8. * @category Resource-Model
  9. * @copyright Copyright (c) 2010 Hettema&Bergsten
  10. * @author
  11. */
  12. abstract class Core_Model_Resource_Abstract extends Core_Model_Object
  13. {
  14. /**
  15. * DB Connections cache
  16. */
  17. protected $_connections = array();
  18. /**
  19. * Main table name
  20. */
  21. protected $_mainTable;
  22. /**
  23. * Main table primary id field name
  24. */
  25. protected $_idFieldName;
  26. /**
  27. * Primery key auto increment flag
  28. */
  29. protected $_isPkAutoIncrement = true;
  30. /**
  31. * @var Mysql_Query
  32. */
  33. protected $_query;
  34. public function __construct()
  35. {
  36. $this->_construct();
  37. }
  38. /**
  39. * Set the main table and id field name
  40. *
  41. * @param string $mainTable
  42. * @param string $idFieldName
  43. */
  44. protected function _init($mainTable, $idFieldName)
  45. {
  46. $this->_setMainTable($mainTable, $idFieldName);
  47. }
  48. /**
  49. * Set the main table and id field name
  50. *
  51. * @param string $mainTable
  52. * @param string $idFieldName
  53. * @return Core_Model_Resource_Abstract
  54. */
  55. protected function _setMainTable($mainTable, $idFieldName=null)
  56. {
  57. $this->_mainTable = $mainTable;
  58. if (is_null($idFieldName)) {
  59. $idFieldName = $mainTable.'_id';
  60. }
  61. $this->_idFieldName = $idFieldName;
  62. return $this;
  63. }
  64. /**
  65. *
  66. * @return string id field name
  67. */
  68. public function getIdFieldName()
  69. {
  70. if (empty($this->_idFieldName)) {
  71. App_Main::throwException('Empty identifier field name');
  72. }
  73. return $this->_idFieldName;
  74. }
  75. /**
  76. *
  77. * @return string main talbe name
  78. */
  79. public function getMainTable()
  80. {
  81. if (empty($this->_mainTable)) {
  82. App_Main::throwException('Empty main table name');
  83. }
  84. return $this->_mainTable;
  85. }
  86. /**
  87. * Get the connection from the connection cache
  88. *
  89. * @param string $connectionName
  90. * @return Main_Mysql connection
  91. */
  92. protected function _getConnection($connectionName)
  93. {
  94. if (isset($this->_connections[$connectionName])) {
  95. return $this->_connections[$connectionName];
  96. } else {
  97. $this->_connections[$connectionName] = App_Main::getDbAdapter();
  98. }
  99. return $this->_connections[$connectionName];
  100. }
  101. /**
  102. * Get the read DB adapter
  103. *
  104. * @return Main_Mysql connection
  105. */
  106. protected function _getReadAdapter()
  107. {
  108. return $this->_getConnection('read');
  109. }
  110. /**
  111. * Get the write DB adapter
  112. *
  113. * @return Main_Mysql connection
  114. */
  115. protected function _getWriteAdapter()
  116. {
  117. return $this->_getConnection('write');
  118. }
  119. /**
  120. * Load an object model data from db
  121. *
  122. * @param Core_Model_Abstract $object
  123. * @param mixed $value
  124. * @param string $field field to load by (defaults to model id)
  125. * @return Core_Model_Resource_Abstract
  126. */
  127. public function load(Core_Model_Abstract $object, $value, $field=null)
  128. {
  129. if (is_null($field)) {
  130. $field = $this->getIdFieldName();
  131. }
  132. $read = $this->_getReadAdapter();
  133. if (!is_null($value)) {
  134. $data = $this->_getReadAdapter()->fetchRow("SELECT * FROM " . $this->getMainTable() . " WHERE ". $field ."='". $value ."'");
  135. if ($data) {
  136. $object->setData($data);
  137. }
  138. }
  139. if($object->getId()) {
  140. $this->_afterLoad($object);
  141. }
  142. return $this;
  143. }
  144. /**
  145. * Process object data after loading
  146. *
  147. * @param Core_Model_Abstract $object
  148. */
  149. protected function _afterLoad(Core_Model_Abstract $object) { }
  150. /**
  151. * Process object before loading
  152. *
  153. * @param Core_Model_Abstract $object
  154. */
  155. protected function _beforeSave(Core_Model_Abstract $object) { }
  156. /**
  157. * Check unique data fields before saving an object data
  158. *
  159. * @param Core_Model_Abstract $object
  160. */
  161. protected function _checkUnique(Core_Model_Abstract $object) {}
  162. /**
  163. * Process object before saving
  164. *
  165. * @param Core_Model_Abstract $object
  166. */
  167. protected function _afterSave(Core_Model_Abstract $object) {}
  168. /**
  169. * Save the object data
  170. *
  171. * @param Core_Model_Abstract $object
  172. * @return Core_Model_Resource_Abstract
  173. */
  174. public function save(Core_Model_Abstract $object)
  175. {
  176. if ($object->isDeleted()) {
  177. return $this->delete($object);
  178. }
  179. $this->_beforeSave($object);
  180. $this->_checkUnique($object);
  181. if (!is_null($object->getId())) {
  182. // Not auto increment primary key support
  183. if ($this->_isPkAutoIncrement) {
  184. $this->_getWriteAdapter()->update($this->getMainTable(), $this->_prepareDataForSave($object), $this->getIdFieldName());
  185. } else {
  186. if ($this->_getWriteAdapter()->fetchOne("SELECT * FROM ". $this->getMainTable() ." WHERE ". $this->getIdFieldName()."=". $object->getId()) !== false) {
  187. $this->_getWriteAdapter()->update($this->getMainTable(), $this->_prepareDataForSave($object), $this->getIdFieldName());
  188. } else {
  189. $this->_getWriteAdapter()->insert($this->getMainTable(), $this->_prepareDataForSave($object, true));
  190. }
  191. }
  192. } else {
  193. $id = $this->_getWriteAdapter()->insert($this->getMainTable(), $this->_prepareDataForSave($object, true), $this->getIdFieldName());
  194. $object->setId($id);
  195. }
  196. $this->_afterSave($object);
  197. return $this;
  198. }
  199. /**
  200. * Process object before deleting
  201. *
  202. * @param Core_Model_Abstract $object
  203. */
  204. protected function _beforeDelete(Core_Model_Abstract $object) {}
  205. /**
  206. * Process object after deleting
  207. *
  208. * @param Core_Model_Abstract $object
  209. */
  210. protected function _afterDelete(Core_Model_Abstract $object) {}
  211. /**
  212. * Delete the object data from database
  213. *
  214. * @param Core_Model_Object $object
  215. */
  216. public function delete(Core_Model_Abstract $object)
  217. {
  218. $this->_beforeDelete($object);
  219. $this->_getWriteAdapter()->delete(
  220. $this->getMainTable(), $this->getIdFieldName() .'='. $object->getId()
  221. );
  222. $this->_afterDelete($object);
  223. return $this;
  224. }
  225. /**
  226. * Prepare the object data for saving to the database
  227. * If $table is null, the main table is used and the fields are identified
  228. *
  229. * @param Core_Model_Abstract $object
  230. * @param bool $graceful
  231. * @param string $table
  232. * @return type
  233. */
  234. protected function _prepareDataForSave(Core_Model_Abstract $object, $graceful = false, $table = false)
  235. {
  236. $data = array();
  237. $table = !$table ? $this->getMainTable() : $table;
  238. $fields = $this->_getWriteAdapter()->describeTable($table);
  239. foreach ($fields as $field=>$fieldInfo) {
  240. if(!$object->hasData($field) && $fieldInfo['Null'] == 'NO') {
  241. if(isset($fieldInfo['Default'])) { continue; }
  242. if(isset($fieldInfo['Key']) && $fieldInfo['Key'] == 'PRI') { continue; } //@# ToDO add the check to auto increment here if needed
  243. }
  244. if($object->hasData($field)) {
  245. $data[$field] = $this->_prepareValueForSave($object->getData($field), $fieldInfo['data_type']);
  246. } else if ($fieldInfo['Null'] == 'NO' && !isset($fieldInfo['Default']) && $graceful) { //set empty string for those field which does not have default value and is nullable
  247. $data[$field] = $this->_prepareValueForSave('');
  248. } else {
  249. continue;
  250. }
  251. }
  252. return $data;
  253. }
  254. /**
  255. * Prepare value for saving
  256. *
  257. * @param mixed $value
  258. * @param string $type
  259. * - int
  260. * - decimal
  261. * - text
  262. * @return type
  263. */
  264. protected function _prepareValueForSave($value, $type='text')
  265. {
  266. switch($type)
  267. {
  268. case 'int': //returns '0' for an empty $value
  269. return (strlen($value) > 10) ? $value : intval($value); #@ToDO make it possible to analyse the data type and return proper int value
  270. break;
  271. case 'decimal':
  272. return floatval($value);
  273. break;
  274. default:
  275. return "'". mysql_real_escape_string($value) ."'";
  276. break;
  277. }
  278. }
  279. /**
  280. *
  281. * @return Main_Mysql_Query object
  282. */
  283. public function _getQuery()
  284. {
  285. if(!$this->_query) {
  286. $this->_query = new Main_Mysql_Query();
  287. }
  288. return $this->_query;
  289. }
  290. }