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

/lib/Cake/Model/Datasource/DataSource.php

https://bitbucket.org/vishallogiciel/admin-bootstrap
PHP | 445 lines | 189 code | 44 blank | 212 comment | 31 complexity | 9e250147c01a7abe368d41d2017b0e6a MD5 | raw file
  1. <?php
  2. /**
  3. * DataSource base class
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * For full copyright and license information, please see the LICENSE.txt
  12. * Redistributions of files must retain the above copyright notice.
  13. *
  14. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  15. * @link http://cakephp.org CakePHP(tm) Project
  16. * @package Cake.Model.Datasource
  17. * @since CakePHP(tm) v 0.10.5.1790
  18. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  19. */
  20. /**
  21. * DataSource base class
  22. *
  23. * DataSources are the link between models and the source of data that models represent.
  24. *
  25. * @link http://book.cakephp.org/2.0/en/models/datasources.html#basic-api-for-datasources
  26. * @package Cake.Model.Datasource
  27. */
  28. class DataSource extends Object {
  29. /**
  30. * Are we connected to the DataSource?
  31. *
  32. * @var boolean
  33. */
  34. public $connected = false;
  35. /**
  36. * The default configuration of a specific DataSource
  37. *
  38. * @var array
  39. */
  40. protected $_baseConfig = array();
  41. /**
  42. * Holds references to descriptions loaded by the DataSource
  43. *
  44. * @var array
  45. */
  46. protected $_descriptions = array();
  47. /**
  48. * Holds a list of sources (tables) contained in the DataSource
  49. *
  50. * @var array
  51. */
  52. protected $_sources = null;
  53. /**
  54. * The DataSource configuration
  55. *
  56. * @var array
  57. */
  58. public $config = array();
  59. /**
  60. * Whether or not this DataSource is in the middle of a transaction
  61. *
  62. * @var boolean
  63. */
  64. protected $_transactionStarted = false;
  65. /**
  66. * Whether or not source data like available tables and schema descriptions
  67. * should be cached
  68. *
  69. * @var boolean
  70. */
  71. public $cacheSources = true;
  72. /**
  73. * Constructor.
  74. *
  75. * @param array $config Array of configuration information for the datasource.
  76. */
  77. public function __construct($config = array()) {
  78. parent::__construct();
  79. $this->setConfig($config);
  80. }
  81. /**
  82. * Caches/returns cached results for child instances
  83. *
  84. * @param mixed $data
  85. * @return array Array of sources available in this datasource.
  86. */
  87. public function listSources($data = null) {
  88. if ($this->cacheSources === false) {
  89. return null;
  90. }
  91. if ($this->_sources !== null) {
  92. return $this->_sources;
  93. }
  94. $key = ConnectionManager::getSourceName($this) . '_' . $this->config['database'] . '_list';
  95. $key = preg_replace('/[^A-Za-z0-9_\-.+]/', '_', $key);
  96. $sources = Cache::read($key, '_cake_model_');
  97. if (empty($sources)) {
  98. $sources = $data;
  99. Cache::write($key, $data, '_cake_model_');
  100. }
  101. return $this->_sources = $sources;
  102. }
  103. /**
  104. * Returns a Model description (metadata) or null if none found.
  105. *
  106. * @param Model|string $model
  107. * @return array Array of Metadata for the $model
  108. */
  109. public function describe($model) {
  110. if ($this->cacheSources === false) {
  111. return null;
  112. }
  113. if (is_string($model)) {
  114. $table = $model;
  115. } else {
  116. $table = $model->tablePrefix . $model->table;
  117. }
  118. if (isset($this->_descriptions[$table])) {
  119. return $this->_descriptions[$table];
  120. }
  121. $cache = $this->_cacheDescription($table);
  122. if ($cache !== null) {
  123. $this->_descriptions[$table] =& $cache;
  124. return $cache;
  125. }
  126. return null;
  127. }
  128. /**
  129. * Begin a transaction
  130. *
  131. * @return boolean Returns true if a transaction is not in progress
  132. */
  133. public function begin() {
  134. return !$this->_transactionStarted;
  135. }
  136. /**
  137. * Commit a transaction
  138. *
  139. * @return boolean Returns true if a transaction is in progress
  140. */
  141. public function commit() {
  142. return $this->_transactionStarted;
  143. }
  144. /**
  145. * Rollback a transaction
  146. *
  147. * @return boolean Returns true if a transaction is in progress
  148. */
  149. public function rollback() {
  150. return $this->_transactionStarted;
  151. }
  152. /**
  153. * Converts column types to basic types
  154. *
  155. * @param string $real Real column type (i.e. "varchar(255)")
  156. * @return string Abstract column type (i.e. "string")
  157. */
  158. public function column($real) {
  159. return false;
  160. }
  161. /**
  162. * Used to create new records. The "C" CRUD.
  163. *
  164. * To-be-overridden in subclasses.
  165. *
  166. * @param Model $model The Model to be created.
  167. * @param array $fields An Array of fields to be saved.
  168. * @param array $values An Array of values to save.
  169. * @return boolean success
  170. */
  171. public function create(Model $model, $fields = null, $values = null) {
  172. return false;
  173. }
  174. /**
  175. * Used to read records from the Datasource. The "R" in CRUD
  176. *
  177. * To-be-overridden in subclasses.
  178. *
  179. * @param Model $model The model being read.
  180. * @param array $queryData An array of query data used to find the data you want
  181. * @param integer $recursive Number of levels of association
  182. * @return mixed
  183. */
  184. public function read(Model $model, $queryData = array(), $recursive = null) {
  185. return false;
  186. }
  187. /**
  188. * Update a record(s) in the datasource.
  189. *
  190. * To-be-overridden in subclasses.
  191. *
  192. * @param Model $model Instance of the model class being updated
  193. * @param array $fields Array of fields to be updated
  194. * @param array $values Array of values to be update $fields to.
  195. * @param mixed $conditions
  196. * @return boolean Success
  197. */
  198. public function update(Model $model, $fields = null, $values = null, $conditions = null) {
  199. return false;
  200. }
  201. /**
  202. * Delete a record(s) in the datasource.
  203. *
  204. * To-be-overridden in subclasses.
  205. *
  206. * @param Model $model The model class having record(s) deleted
  207. * @param mixed $conditions The conditions to use for deleting.
  208. * @return boolean Success
  209. */
  210. public function delete(Model $model, $id = null) {
  211. return false;
  212. }
  213. /**
  214. * Returns the ID generated from the previous INSERT operation.
  215. *
  216. * @param mixed $source
  217. * @return mixed Last ID key generated in previous INSERT
  218. */
  219. public function lastInsertId($source = null) {
  220. return false;
  221. }
  222. /**
  223. * Returns the number of rows returned by last operation.
  224. *
  225. * @param mixed $source
  226. * @return integer Number of rows returned by last operation
  227. */
  228. public function lastNumRows($source = null) {
  229. return false;
  230. }
  231. /**
  232. * Returns the number of rows affected by last query.
  233. *
  234. * @param mixed $source
  235. * @return integer Number of rows affected by last query.
  236. */
  237. public function lastAffected($source = null) {
  238. return false;
  239. }
  240. /**
  241. * Check whether the conditions for the Datasource being available
  242. * are satisfied. Often used from connect() to check for support
  243. * before establishing a connection.
  244. *
  245. * @return boolean Whether or not the Datasources conditions for use are met.
  246. */
  247. public function enabled() {
  248. return true;
  249. }
  250. /**
  251. * Sets the configuration for the DataSource.
  252. * Merges the $config information with the _baseConfig and the existing $config property.
  253. *
  254. * @param array $config The configuration array
  255. * @return void
  256. */
  257. public function setConfig($config = array()) {
  258. $this->config = array_merge($this->_baseConfig, $this->config, $config);
  259. }
  260. /**
  261. * Cache the DataSource description
  262. *
  263. * @param string $object The name of the object (model) to cache
  264. * @param mixed $data The description of the model, usually a string or array
  265. * @return mixed
  266. */
  267. protected function _cacheDescription($object, $data = null) {
  268. if ($this->cacheSources === false) {
  269. return null;
  270. }
  271. if ($data !== null) {
  272. $this->_descriptions[$object] =& $data;
  273. }
  274. $key = ConnectionManager::getSourceName($this) . '_' . $object;
  275. $cache = Cache::read($key, '_cake_model_');
  276. if (empty($cache)) {
  277. $cache = $data;
  278. Cache::write($key, $cache, '_cake_model_');
  279. }
  280. return $cache;
  281. }
  282. /**
  283. * Replaces `{$__cakeID__$}` and `{$__cakeForeignKey__$}` placeholders in query data.
  284. *
  285. * @param string $query Query string needing replacements done.
  286. * @param array $data Array of data with values that will be inserted in placeholders.
  287. * @param string $association Name of association model being replaced
  288. * @param array $assocData
  289. * @param Model $model Instance of the model to replace $__cakeID__$
  290. * @param Model $linkModel Instance of model to replace $__cakeForeignKey__$
  291. * @param array $stack
  292. * @return string String of query data with placeholders replaced.
  293. */
  294. public function insertQueryData($query, $data, $association, $assocData, Model $model, Model $linkModel, $stack) {
  295. $keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}');
  296. foreach ($keys as $key) {
  297. $val = null;
  298. $type = null;
  299. if (strpos($query, $key) !== false) {
  300. switch ($key) {
  301. case '{$__cakeID__$}':
  302. if (isset($data[$model->alias]) || isset($data[$association])) {
  303. if (isset($data[$model->alias][$model->primaryKey])) {
  304. $val = $data[$model->alias][$model->primaryKey];
  305. } elseif (isset($data[$association][$model->primaryKey])) {
  306. $val = $data[$association][$model->primaryKey];
  307. }
  308. } else {
  309. $found = false;
  310. foreach (array_reverse($stack) as $assoc) {
  311. if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) {
  312. $val = $data[$assoc][$model->primaryKey];
  313. $found = true;
  314. break;
  315. }
  316. }
  317. if (!$found) {
  318. $val = '';
  319. }
  320. }
  321. $type = $model->getColumnType($model->primaryKey);
  322. break;
  323. case '{$__cakeForeignKey__$}':
  324. foreach ($model->associations() as $name) {
  325. foreach ($model->$name as $assocName => $assoc) {
  326. if ($assocName === $association) {
  327. if (isset($assoc['foreignKey'])) {
  328. $foreignKey = $assoc['foreignKey'];
  329. $assocModel = $model->$assocName;
  330. $type = $assocModel->getColumnType($assocModel->primaryKey);
  331. if (isset($data[$model->alias][$foreignKey])) {
  332. $val = $data[$model->alias][$foreignKey];
  333. } elseif (isset($data[$association][$foreignKey])) {
  334. $val = $data[$association][$foreignKey];
  335. } else {
  336. $found = false;
  337. foreach (array_reverse($stack) as $assoc) {
  338. if (isset($data[$assoc]) && isset($data[$assoc][$foreignKey])) {
  339. $val = $data[$assoc][$foreignKey];
  340. $found = true;
  341. break;
  342. }
  343. }
  344. if (!$found) {
  345. $val = '';
  346. }
  347. }
  348. }
  349. break 3;
  350. }
  351. }
  352. }
  353. break;
  354. }
  355. if (empty($val) && $val !== '0') {
  356. return false;
  357. }
  358. $query = str_replace($key, $this->value($val, $type), $query);
  359. }
  360. }
  361. return $query;
  362. }
  363. /**
  364. * To-be-overridden in subclasses.
  365. *
  366. * @param Model $model Model instance
  367. * @param string $key Key name to make
  368. * @return string Key name for model.
  369. */
  370. public function resolveKey(Model $model, $key) {
  371. return $model->alias . $key;
  372. }
  373. /**
  374. * Returns the schema name. Override this in subclasses.
  375. *
  376. * @return string schema name
  377. */
  378. public function getSchemaName() {
  379. return null;
  380. }
  381. /**
  382. * Closes a connection. Override in subclasses
  383. *
  384. * @return boolean
  385. */
  386. public function close() {
  387. return $this->connected = false;
  388. }
  389. /**
  390. * Closes the current datasource.
  391. *
  392. */
  393. public function __destruct() {
  394. if ($this->_transactionStarted) {
  395. $this->rollback();
  396. }
  397. if ($this->connected) {
  398. $this->close();
  399. }
  400. }
  401. }