PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Ecart/Db/Table/Abstract.php

https://code.google.com/p/ecartcommerce/
PHP | 451 lines | 248 code | 50 blank | 153 comment | 29 complexity | 98c59d9fe3d153921977a2b01d882a8b MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Ecart
  4. *
  5. * This file is part of Ecart.
  6. *
  7. * Ecart is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * Ecart is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with Ecart. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. * @category Ecart
  21. * @package Ecart_Db
  22. * @copyright Copyright 2008-2009 E-Cart LLC
  23. * @license GNU Public License V3.0
  24. */
  25. /**
  26. *
  27. * @category Ecart
  28. * @package Ecart_Db
  29. * @author Ecart Core Team <core@ecartcommerce.com>
  30. */
  31. abstract class Ecart_Db_Table_Abstract extends Zend_Db_Table_Abstract
  32. {
  33. /**
  34. * @var string
  35. */
  36. protected $_name = null;
  37. protected $_rowClass = 'Ecart_Db_Table_Row';
  38. protected $_rowsetClass = 'Ecart_Db_Table_Rowset';
  39. const SELECT_CLASS = 'selectClass';
  40. protected $_selectClass = 'Ecart_Db_Table_Select';
  41. const PREFIX = 'prefix';
  42. /**
  43. * @var string
  44. */
  45. protected $_prefix = null;
  46. /**
  47. * Initialize table and schema names.
  48. *
  49. * If the table name is not set in the class definition,
  50. * use the class name itself as the table name.
  51. *
  52. * A schema name provided with the table name (e.g., "schema.table") overrides
  53. * any existing value for $this->_schema.
  54. *
  55. * @return void
  56. */
  57. protected function _setupTableName()
  58. {
  59. parent::_setupTableName();
  60. $this->_prefix = Ecart::config()->db->prefix;
  61. $this->_name = $this->_prefix . $this->_name;
  62. }
  63. /**
  64. * setOptions()
  65. *
  66. * @param array $options
  67. * @return Ecart_Db_Table_Abstract
  68. */
  69. public function setOptions(Array $options)
  70. {
  71. //@todo now never used, need create Ecart_Db factory with
  72. if (isset($options[self::PREFIX])) {
  73. $this->_prefix = $options[self::PREFIX];
  74. }
  75. if (isset($options[self::SELECT_CLASS])) {
  76. $this->setSelectClass($options[self::SELECT_CLASS]);
  77. }
  78. return parent::setOptions($options);
  79. }
  80. /**
  81. * Returns table information.
  82. *
  83. * You can elect to return only a part of this information by supplying its key name,
  84. * otherwise all information is returned as an array.
  85. *
  86. * @param $key The specific info part to return OPTIONAL
  87. * @return mixed
  88. */
  89. public function info($key = null)
  90. {
  91. $this->_setupPrimaryKey();
  92. $info = array(
  93. self::SCHEMA => $this->_schema,
  94. self::NAME => $this->_name,
  95. self::PREFIX => $this->_prefix,
  96. self::COLS => $this->_getCols(),
  97. self::PRIMARY => (array) $this->_primary,
  98. self::METADATA => $this->_metadata,
  99. self::ROW_CLASS => $this->getRowClass(),
  100. self::ROWSET_CLASS => $this->getRowsetClass(),
  101. self::SELECT_CLASS => $this->getSelectClass(),
  102. self::REFERENCE_MAP => $this->_referenceMap,
  103. self::DEPENDENT_TABLES => $this->_dependentTables,
  104. self::SEQUENCE => $this->_sequence
  105. );
  106. if ($key === null) {
  107. return $info;
  108. }
  109. if (!array_key_exists($key, $info)) {
  110. require_once 'Zend/Db/Table/Exception.php';
  111. throw new Zend_Db_Table_Exception(
  112. 'There is no table information for the key "' . $key . '"'
  113. );
  114. }
  115. return $info[$key];
  116. }
  117. /**
  118. *
  119. * @param string $name
  120. * @return string
  121. */
  122. public function getTableName($name = null)
  123. {
  124. if (null === $name) {
  125. return $this->_name;
  126. }
  127. return $this->_prefix . $name;
  128. }
  129. /**
  130. * @param string $classname
  131. * @return Zend_Db_Table_Abstract Provides a fluent interface
  132. */
  133. public function setSelectClass($selectClass)
  134. {
  135. $this->_selectClass = $selectClass;
  136. return $this;
  137. }
  138. /**
  139. *
  140. * @return string
  141. */
  142. public function getSelectClass()
  143. {
  144. return $this->_selectClass;
  145. }
  146. /**
  147. * @param mixed $columns array, string, Zend_Db_Expr
  148. * @return Ecart_Db_Table_Select
  149. * @throws Ecart_Exception
  150. */
  151. public function select($columns = array())
  152. {
  153. $className = $this->getSelectClass();
  154. $select = new $className($this);
  155. if (!$select instanceof Ecart_Db_Table_Select) {
  156. throw new Ecart_Exception(Ecart::translate('core')->__(
  157. 'Instance of %s expected, %s given',
  158. 'Ecart_Db_Table_Select' ,
  159. $className
  160. ));
  161. }
  162. if (!empty($columns)) {
  163. $select->from(
  164. substr($this->_name, strlen($this->_prefix)),
  165. $columns,
  166. $this->info(Zend_Db_Table_Abstract::SCHEMA)
  167. );
  168. }
  169. return $select;
  170. }
  171. /**
  172. *
  173. * @method string hasName
  174. * @method int getName
  175. * @method int getNameById
  176. * @method string cntName
  177. * @example Ecart::single('core/template')->getNameById(1)
  178. * -//- ->getName(1) used first primary key
  179. * -//- ->getIdByName('default')
  180. * -//- ->hasName('default')
  181. * -//- ->cntFieldName('try') count by field "field_name" = 'try'
  182. */
  183. public function __call($call, $argv)
  184. {
  185. // $columns = array_keys($this->_db->describeTable(
  186. // $this->_prefix . $this->_name, $this->_schema)
  187. // );
  188. // $columns = $this->info('cols');
  189. $fields = explode('By', substr($call, 3));
  190. // if(false === function_exists('camelize')) {
  191. // function camelize($str) {
  192. // $str = str_replace(" ", "", ucwords(str_replace("_", " ", $str)));
  193. // return (string)(strtolower(substr($str, 0, 1)) . substr($str, 1));
  194. // }
  195. // }
  196. if(false === function_exists('underscore')) {
  197. function underscore($str = null) {
  198. return strtolower(
  199. preg_replace(
  200. array('/(.)([A-Z])/', '/(.)(\d+)/'), "$1_$2", $str
  201. )
  202. );
  203. }
  204. }
  205. $ruturnField = underscore($fields[0]);
  206. if (isset($fields[1])) {
  207. $conditionField = underscore($fields[1]);
  208. }
  209. if (!isset($conditionField)
  210. || null === $conditionField
  211. || !$conditionField) {
  212. $conditionField = current($this->info('primary'));
  213. }
  214. // if (!in_array($conditionField, $columns)
  215. // || !in_array($ruturnField, $columns)) {
  216. //
  217. // throw new Ecart_Exception(
  218. // Ecart::translate('core')->__('Incorrect condition ') .
  219. // $call . ' ( ' . $ruturnField . ', ' .$conditionField . ' )'
  220. // );
  221. // }
  222. $conditionValue = current($argv);
  223. if (null === $conditionValue) {
  224. throw new Ecart_Exception(
  225. Ecart::translate('core')->__(
  226. 'Condition "%" is null', $conditionField
  227. )
  228. );
  229. }
  230. switch (substr($call, 0, 3)) {
  231. case 'get':
  232. return $this->getAdapter()->fetchOne(
  233. "SELECT {$ruturnField} FROM " . $this->_name
  234. . " WHERE {$conditionField} = ? ",
  235. $conditionValue
  236. );
  237. case 'has':
  238. $count = $this->getAdapter()->fetchOne(
  239. 'SELECT COUNT(*) FROM ' . $this->_name
  240. . " WHERE {$ruturnField} = ?",
  241. $conditionValue
  242. );
  243. return $count ? true : false;
  244. case 'cnt':
  245. $count = $this->getAdapter()->fetchOne(
  246. 'SELECT COUNT(*) FROM ' . $this->_name
  247. . " WHERE {$ruturnField} = ?",
  248. $conditionValue
  249. );
  250. return $count;
  251. }
  252. throw new Ecart_Exception(Ecart::translate('core')->__(
  253. "Call to undefined method %s", get_class($this) . '::' . $call
  254. ));
  255. }
  256. /**
  257. * @todo remove this, need use Ecart::message in controllers
  258. *
  259. * @param array $data Column-value pairs.
  260. * @return mixed The primary key of the row inserted.
  261. */
  262. public function insert(array $data)
  263. {
  264. try {
  265. return parent::insert($data);
  266. } catch (Exception $e) {
  267. Ecart::message()->addError($e->getMessage());
  268. return false;
  269. }
  270. }
  271. /**
  272. * * @todo remove this, need use Ecart::message in controllers
  273. *
  274. * @param array $data Column-value pairs.
  275. * @param array|string $where An SQL WHERE clause, or an array of SQL WHERE clauses.
  276. * @return int The number of rows updated.
  277. */
  278. public function update(array $data, $where)
  279. {
  280. try {
  281. return parent::update($data, $where);
  282. } catch (Exception $e) {
  283. Ecart::message()->addError($e->getMessage());
  284. return false;
  285. }
  286. }
  287. /**
  288. * @todo remove this, need use Ecart::message in controllers
  289. *
  290. * @param array|string $where SQL WHERE clause(s).
  291. * @return int The number of rows deleted.
  292. */
  293. public function delete($where)
  294. {
  295. try {
  296. return parent::delete($where);
  297. } catch (Exception $e) {
  298. Ecart::message()->addError($e->getMessage());
  299. return false;
  300. }
  301. }
  302. /**
  303. *
  304. * @return Ecart_Db_Table_Abstract
  305. */
  306. public function cache()
  307. {
  308. $frontend = Ecart::single('Ecart_Cache_Frontend_Query');
  309. if (func_num_args()) {
  310. $args = serialize(func_get_args());
  311. return $frontend->setInstance($this, $args);
  312. }
  313. return $frontend->setInstance($this);
  314. }
  315. /**
  316. * Fetches all rows.
  317. *
  318. * Honors the Zend_Db_Adapter fetch mode.
  319. *
  320. * @param string|array|Zend_Db_Table_Select $where OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object.
  321. * @param string|array $order OPTIONAL An SQL ORDER clause.
  322. * @param int $count OPTIONAL An SQL LIMIT count.
  323. * @param int $offset OPTIONAL An SQL LIMIT offset.
  324. * @return Zend_Db_Table_Rowset_Abstract The row results per the Zend_Db_Adapter fetch mode.
  325. */
  326. public function fetchAll($where = null, $order = null, $count = null, $offset = null)
  327. {
  328. if (!($where instanceof Zend_Db_Table_Select)) {
  329. $select = $this->select()
  330. ->setUseCollerationName(false)
  331. ->setIntegrityCheck();
  332. if ($where !== null) {
  333. $this->_where($select, $where);
  334. }
  335. if ($order !== null) {
  336. $this->_order($select, $order);
  337. }
  338. if ($count !== null || $offset !== null) {
  339. $select->limit($count, $offset);
  340. }
  341. } else {
  342. $select = $where;
  343. }
  344. $rows = $this->_fetch($select);
  345. $data = array(
  346. 'table' => $this,
  347. 'data' => $rows,
  348. 'readOnly' => $select->isReadOnly(),
  349. 'rowClass' => $this->getRowClass(),
  350. 'stored' => true
  351. );
  352. $rowsetClass = $this->getRowsetClass();
  353. if (!class_exists($rowsetClass)) {
  354. require_once 'Zend/Loader.php';
  355. Zend_Loader::loadClass($rowsetClass);
  356. }
  357. return new $rowsetClass($data);
  358. }
  359. /**
  360. * Fetches one row in an object of type Zend_Db_Table_Row_Abstract,
  361. * or returns null if no row matches the specified criteria.
  362. *
  363. * @param string|array|Zend_Db_Table_Select $where OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object.
  364. * @param string|array $order OPTIONAL An SQL ORDER clause.
  365. * @return Zend_Db_Table_Row_Abstract|null The row results per the
  366. * Zend_Db_Adapter fetch mode, or null if no row found.
  367. */
  368. public function fetchRow($where = null, $order = null)
  369. {
  370. if (!($where instanceof Zend_Db_Table_Select)) {
  371. $select = $this->select()
  372. ->setUseCollerationName(false)
  373. ->setIntegrityCheck();
  374. if ($where !== null) {
  375. $this->_where($select, $where);
  376. }
  377. if ($order !== null) {
  378. $this->_order($select, $order);
  379. }
  380. $select->limit(1);
  381. } else {
  382. $select = $where->limit(1);
  383. }
  384. $rows = $this->_fetch($select);
  385. if (count($rows) == 0) {
  386. return null;
  387. }
  388. $data = array(
  389. 'table' => $this,
  390. 'data' => $rows[0],
  391. 'readOnly' => $select->isReadOnly(),
  392. 'stored' => true
  393. );
  394. $rowClass = $this->getRowClass();
  395. if (!class_exists($rowClass)) {
  396. require_once 'Zend/Loader.php';
  397. Zend_Loader::loadClass($rowClass);
  398. }
  399. return new $rowClass($data);
  400. }
  401. }