PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Propel/Runtime/ActiveQuery/Criterion/AbstractCriterion.php

https://gitlab.com/lcp0578/Propel2
PHP | 392 lines | 180 code | 47 blank | 165 comment | 17 complexity | 28fd38cbfd73e7aedd13f3e6bdb6236a MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. namespace Propel\Runtime\ActiveQuery\Criterion;
  10. use Propel\Runtime\Propel;
  11. use Propel\Runtime\ActiveQuery\Criteria;
  12. use Propel\Runtime\Exception\PropelException;
  13. use Propel\Runtime\Adapter\AdapterInterface;
  14. use Propel\Runtime\Map\ColumnMap;
  15. /**
  16. * This is an "inner" class that describes an object in the criteria.
  17. *
  18. * In Torque this is an inner class of the Criteria class.
  19. *
  20. * @author Hans Lellelid <hans@xmpl.org> (Propel)
  21. */
  22. abstract class AbstractCriterion
  23. {
  24. const UND = " AND ";
  25. const ODER = " OR ";
  26. /** Value of the criterion */
  27. protected $value;
  28. /**
  29. * Comparison value.
  30. * @var string
  31. */
  32. protected $comparison;
  33. /**
  34. * Table name
  35. * @var string
  36. */
  37. protected $table;
  38. /**
  39. * Real table name
  40. * @var string
  41. */
  42. protected $realtable;
  43. /**
  44. * Column name
  45. * @var string
  46. */
  47. protected $column;
  48. /**
  49. * The DBAdapter which might be used to get db specific
  50. * variations of sql.
  51. */
  52. protected $db;
  53. /**
  54. * Other connected criterions
  55. * @var AbstractCriterion[]
  56. */
  57. protected $clauses = array();
  58. /**
  59. * Operators for connected criterions
  60. * Only self::UND and self::ODER are accepted
  61. * @var string[]
  62. */
  63. protected $conjunctions = array();
  64. /**
  65. * Create a new instance.
  66. *
  67. * @param Criteria $outer The outer class (this is an "inner" class).
  68. * @param string $column TABLE.COLUMN format.
  69. * @param mixed $value
  70. * @param string $comparison
  71. */
  72. public function __construct(Criteria $outer, $column, $value, $comparison = null)
  73. {
  74. $this->value = $value;
  75. $this->setColumn($column);
  76. $this->comparison = (null === $comparison) ? Criteria::EQUAL : $comparison;
  77. $this->init($outer);
  78. }
  79. /**
  80. * Init some properties with the help of outer class
  81. * @param Criteria $criteria The outer class
  82. */
  83. public function init(Criteria $criteria)
  84. {
  85. try {
  86. $db = Propel::getServiceContainer()->getAdapter($criteria->getDbName());
  87. $this->setAdapter($db);
  88. } catch (\Exception $e) {
  89. // we are only doing this to allow easier debugging, so
  90. // no need to throw up the exception, just make note of it.
  91. Propel::log("Could not get a AdapterInterface, sql may be wrong", Propel::LOG_ERR);
  92. }
  93. // init $this->realtable
  94. $realtable = $criteria->getTableForAlias($this->table);
  95. $this->realtable = $realtable ? $realtable : $this->table;
  96. }
  97. /**
  98. * Set the $column and $table properties based on a column name or object
  99. */
  100. protected function setColumn($column)
  101. {
  102. if ($column instanceof ColumnMap) {
  103. $this->column = $column->getName();
  104. $this->table = $column->getTable()->getName();
  105. } else {
  106. $dotPos = strrpos($column, '.');
  107. if ($dotPos === false) {
  108. // no dot => aliased column
  109. $this->table = null;
  110. $this->column = $column;
  111. } else {
  112. $this->table = substr($column, 0, $dotPos);
  113. $this->column = substr($column, $dotPos + 1, strlen($column));
  114. }
  115. }
  116. }
  117. /**
  118. * Get the column name.
  119. *
  120. * @return string A String with the column name.
  121. */
  122. public function getColumn()
  123. {
  124. return $this->column;
  125. }
  126. /**
  127. * Set the table name.
  128. *
  129. * @param string $name A String with the table name.
  130. * @return void
  131. */
  132. public function setTable($name)
  133. {
  134. $this->table = $name;
  135. }
  136. /**
  137. * Get the table name.
  138. *
  139. * @return string A String with the table name.
  140. */
  141. public function getTable()
  142. {
  143. return $this->table;
  144. }
  145. /**
  146. * Get the comparison.
  147. *
  148. * @return string A String with the comparison.
  149. */
  150. public function getComparison()
  151. {
  152. return $this->comparison;
  153. }
  154. /**
  155. * Get the value.
  156. *
  157. * @return mixed An Object with the value.
  158. */
  159. public function getValue()
  160. {
  161. return $this->value;
  162. }
  163. /**
  164. * Get the adapter.
  165. *
  166. * The AdapterInterface which might be used to get db specific
  167. * variations of sql.
  168. * @return AdapterInterface value of db.
  169. */
  170. public function getAdapter()
  171. {
  172. return $this->db;
  173. }
  174. /**
  175. * Set the adapter.
  176. *
  177. * The AdapterInterface might be used to get db specific variations of sql.
  178. * @param AdapterInterface $v Value to assign to db.
  179. * @return void
  180. */
  181. public function setAdapter(AdapterInterface $v)
  182. {
  183. $this->db = $v;
  184. foreach ($this->clauses as $clause) {
  185. $clause->setAdapter($v);
  186. }
  187. }
  188. /**
  189. * Get the list of clauses in this Criterion.
  190. * @return self[]
  191. */
  192. private function getClauses()
  193. {
  194. return $this->clauses;
  195. }
  196. /**
  197. * Get the list of conjunctions in this Criterion
  198. * @return array
  199. */
  200. public function getConjunctions()
  201. {
  202. return $this->conjunctions;
  203. }
  204. /**
  205. * Append an AND Criterion onto this Criterion's list.
  206. *
  207. * @param AbstractCriterion $criterion
  208. * @return $this|AbstractCriterion
  209. */
  210. public function addAnd(AbstractCriterion $criterion)
  211. {
  212. $this->clauses[] = $criterion;
  213. $this->conjunctions[] = self::UND;
  214. return $this;
  215. }
  216. /**
  217. * Append an OR Criterion onto this Criterion's list.
  218. *
  219. * @param AbstractCriterion $criterion
  220. * @return $this|AbstractCriterion
  221. */
  222. public function addOr(AbstractCriterion $criterion)
  223. {
  224. $this->clauses[] = $criterion;
  225. $this->conjunctions[] = self::ODER;
  226. return $this;
  227. }
  228. /**
  229. * Appends a Prepared Statement representation of the Criterion
  230. * onto the buffer.
  231. *
  232. * @param string &$sb The string that will receive the Prepared Statement
  233. * @param array $params A list to which Prepared Statement parameters will be appended
  234. * @return void
  235. * @throws PropelException - if the expression builder cannot figure out how to turn a specified
  236. * expression into proper SQL.
  237. */
  238. public function appendPsTo(&$sb, array &$params)
  239. {
  240. if (!$this->clauses) {
  241. return $this->appendPsForUniqueClauseTo($sb, $params);
  242. }
  243. // if there are sub criterions, they must be combined to this criterion
  244. $sb .= str_repeat('(', count($this->clauses));
  245. $this->appendPsForUniqueClauseTo($sb, $params);
  246. foreach ($this->clauses as $key => $clause) {
  247. $sb .= $this->conjunctions[$key];
  248. $clause->appendPsTo($sb, $params);
  249. $sb .= ')';
  250. }
  251. }
  252. public function __toString()
  253. {
  254. $sb = '';
  255. $params = [];
  256. $this->appendPsTo($sb, $params);
  257. return "" . $sb;
  258. }
  259. /**
  260. * Appends a Prepared Statement representation of the Criterion onto the buffer
  261. *
  262. * @param string &$sb The string that will receive the Prepared Statement
  263. * @param array $params A list to which Prepared Statement parameters will be appended
  264. */
  265. abstract protected function appendPsForUniqueClauseTo(&$sb, array &$params);
  266. /**
  267. * This method checks another Criteria to see if they contain
  268. * the same attributes and hashtable entries.
  269. * @return boolean
  270. */
  271. public function equals($obj)
  272. {
  273. // TODO: optimize me with early outs
  274. if ($this === $obj) {
  275. return true;
  276. }
  277. if ((null === $obj) || !($obj instanceof AbstractCriterion)) {
  278. return false;
  279. }
  280. /** @var AbstractCriterion $crit */
  281. $crit = $obj;
  282. $isEquiv = (((null === $this->table && null === $crit->getTable())
  283. || (null !== $this->table && $this->table === $crit->getTable()))
  284. && $this->column === $crit->getColumn()
  285. && $this->comparison === $crit->getComparison())
  286. ;
  287. // check chained criterion
  288. $clausesLength = count($this->clauses);
  289. $isEquiv &= (count($crit->getClauses()) == $clausesLength);
  290. $critConjunctions = $crit->getConjunctions();
  291. $critClauses = $crit->getClauses();
  292. for ($i = 0; $i < $clausesLength && $isEquiv; $i++) {
  293. $isEquiv &= ($this->conjunctions[$i] === $critConjunctions[$i]);
  294. $isEquiv &= ($this->clauses[$i] === $critClauses[$i]);
  295. }
  296. if ($isEquiv) {
  297. $isEquiv &= $this->value === $crit->getValue();
  298. }
  299. return $isEquiv;
  300. }
  301. /**
  302. * Get all tables from nested criterion objects
  303. * @return array
  304. */
  305. public function getAllTables()
  306. {
  307. $tables = array();
  308. $this->addCriterionTable($this, $tables);
  309. return $tables;
  310. }
  311. /**
  312. * method supporting recursion through all criterions to give
  313. * us a string array of tables from each criterion
  314. * @return void
  315. */
  316. private function addCriterionTable(AbstractCriterion $c, array &$s)
  317. {
  318. $s[] = $c->getTable();
  319. foreach ($c->getClauses() as $clause) {
  320. $this->addCriterionTable($clause, $s);
  321. }
  322. }
  323. /**
  324. * get an array of all criterion attached to this
  325. * recursing through all sub criterion
  326. * @return AbstractCriterion[]
  327. */
  328. public function getAttachedCriterion()
  329. {
  330. $criterions = array($this);
  331. foreach ($this->getClauses() as $criterion) {
  332. $criterions = array_merge($criterions, $criterion->getAttachedCriterion());
  333. }
  334. return $criterions;
  335. }
  336. /**
  337. * Ensures deep cloning of attached objects
  338. */
  339. public function __clone()
  340. {
  341. foreach ($this->clauses as $key => $criterion) {
  342. $this->clauses[$key] = clone $criterion;
  343. }
  344. }
  345. }