PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/dmCorePlugin/lib/doctrine/query/dmDoctrineQuery.php

http://github.com/diem-project/diem
PHP | 377 lines | 247 code | 59 blank | 71 comment | 29 complexity | bbff57e07786529f07d47afa72b87c12 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, ISC
  1. <?php
  2. abstract class dmDoctrineQuery extends Doctrine_Query
  3. {
  4. /**
  5. * @var dmModuleManager
  6. */
  7. protected static $moduleManager;
  8. /**
  9. * Constructor.
  10. *
  11. * @param Doctrine_Connection The connection object the query will use.
  12. * @param Doctrine_Hydrator_Abstract The hydrator that will be used for generating result sets.
  13. */
  14. public function __construct(Doctrine_Connection $connection = null, Doctrine_Hydrator_Abstract $hydrator = null)
  15. {
  16. parent::__construct($connection, $hydrator);
  17. if (function_exists('dql_tokenize_query'))
  18. {
  19. //@todo is this a good name for this ?
  20. $this->_tokenizer = new myDoctrineQueryTokenizer();
  21. }
  22. }
  23. /**
  24. * Join translation results if they exist
  25. * if $model is specified, will verify that it has I18n
  26. * return @myDoctrineQuery $this
  27. */
  28. public function withI18n($culture = null, $model = null, $rootAlias = null, $joinSide = 'left')
  29. {
  30. if (null === $model)
  31. {
  32. $_rootAlias = $this->getRootAlias();
  33. $from = explode(' ', $this->_dqlParts['from'][0]);
  34. $model = $from[0];
  35. if(strlen($model) === 0){
  36. $this->getRootAlias();
  37. $models = array_keys($this->_queryComponents);
  38. $model = $models[0];
  39. }
  40. }
  41. if (!dmDb::table($model)->hasI18n())
  42. {
  43. return $this;
  44. }
  45. $culture = null === $culture ? myDoctrineRecord::getDefaultCulture() : $culture;
  46. if (null === $rootAlias)
  47. {
  48. // refresh query for introspection
  49. if(empty($this->_execParams))
  50. {
  51. //prevent bugs for subqueries
  52. $this->fixArrayParameterValues($this->_params);
  53. }
  54. $this->buildSqlQuery();
  55. $rootAlias = $this->getRootAlias();
  56. $translationAlias = $rootAlias.'Translation';
  57. // i18n already joined
  58. if ($this->hasAliasDeclaration($translationAlias))
  59. {
  60. return $this;
  61. }
  62. }
  63. else
  64. {
  65. $translationAlias = $rootAlias.'Translation';
  66. }
  67. $joinMethod = $joinSide.'Join';
  68. return $this->$joinMethod($rootAlias.'.Translation '.$translationAlias.' ON '.$rootAlias.'.id = '.$translationAlias.'.id AND '.$translationAlias.'.lang = ?', $culture);
  69. }
  70. /**
  71. * Join media for this columnName or alias
  72. * return @dmDoctrineQuery $this
  73. */
  74. public function withDmMedia($alias, $rootAlias = null)
  75. {
  76. $rootAlias = $rootAlias ? $rootAlias : $this->getRootAlias();
  77. $mediaJoinAlias = $rootAlias.dmString::camelize($alias);
  78. $folderJoinAlias = $mediaJoinAlias.'Folder';
  79. return $this->leftJoin(sprintf('%s.%s %s, %s.%s %s', $rootAlias, $alias, $mediaJoinAlias, $mediaJoinAlias, 'Folder', $folderJoinAlias));
  80. }
  81. public function whereIsActive($boolean = true, $model = null)
  82. {
  83. if (null !== $model)
  84. {
  85. $table = dmDb::table($model);
  86. if (!$table->hasField('is_active'))
  87. {
  88. return $this;
  89. }
  90. if($table->isI18nColumn('is_active'))
  91. {
  92. // will join i18n if missing
  93. $this->withI18n();
  94. $translationAlias = $this->getRootAlias().'Translation';
  95. return $this->addWhere($translationAlias.'.is_active = ?', (bool) $boolean);
  96. }
  97. }
  98. return $this->addWhere($this->getRootAlias().'.is_active = ?', (bool) $boolean);
  99. }
  100. /**
  101. * Will restrict results to $model records
  102. * associated with $ancestor record
  103. */
  104. public function whereAncestor(myDoctrineRecord $ancestorRecord, $model)
  105. {
  106. return $this->whereAncestorId(get_class($ancestorRecord), $ancestorRecord->get('id'), $model);
  107. }
  108. /**
  109. * Will restrict results to $model records
  110. * associated with $ancestorModel->$ancestorId record
  111. */
  112. #TODO optimize speed by not fetching $ancestorRecord
  113. public function whereAncestorId($ancestorRecordModel, $ancestorRecordId, $model)
  114. {
  115. if(!$module = self::$moduleManager->getModuleByModel($model))
  116. {
  117. throw new dmException(sprintf('No module with model %s', $model));
  118. }
  119. $ancestorModule = self::$moduleManager->getModuleByModel($ancestorRecordModel);
  120. if ($module->hasLocal($ancestorModule))
  121. {
  122. $this->addWhere(sprintf('%s.%s = ?',
  123. $this->getRootAlias(),
  124. $module->getTable()->getRelationHolder()->getLocalByClass($ancestorRecordModel)->getLocal()
  125. ),
  126. $ancestorRecordId
  127. );
  128. }
  129. elseif ($module->hasAssociation($ancestorModule))
  130. {
  131. $this->leftJoin(sprintf('%s.%s %s',
  132. $this->getRootAlias(),
  133. $module->getTable()->getRelationHolder()->getByClass($ancestorRecordModel)->getAlias(),
  134. $ancestorModule->getKey()
  135. ))
  136. ->addWhere($ancestorModule->getKey().'.id = ?', $ancestorRecordId);
  137. }
  138. elseif($module->hasAncestor($ancestorModule))
  139. {
  140. $current = $module;
  141. $currentAlias = $this->getRootAlias();
  142. foreach(array_reverse($module->getPath(), true) as $ancestorKey => $ancestor)
  143. {
  144. if (!$relation = $current->getTable()->getRelationHolder()->getByClass($ancestor->getModel()))
  145. {
  146. throw new dmRecordException(sprintf('%s has no relation for class %s', $current, $ancestor->getModel()));
  147. return null;
  148. }
  149. $this->leftJoin($currentAlias.'.'.$relation->getAlias().' '.$ancestorKey);
  150. if ($ancestor->is($ancestorModule))
  151. {
  152. break;
  153. }
  154. $current = $ancestor;
  155. $currentAlias = $ancestor->getKey();
  156. }
  157. $this->addWhere($ancestorModule->getKey().'.id = ?', $ancestorRecordId);
  158. }
  159. else
  160. {
  161. throw new dmRecordException(sprintf('%s is not an ancestor of %s, nor associated', $ancestorRecordModel, $module));
  162. return null;
  163. }
  164. return $this;
  165. }
  166. /**
  167. * Will restrict results to $model records
  168. * associated with $descendant record
  169. */
  170. public function whereDescendant(myDoctrineRecord $descendantRecord, $model)
  171. {
  172. return $this->whereDescendantId(get_class($descendantRecord), $descendantRecord->get('id'), $model);
  173. }
  174. /**
  175. * Will restrict results to $model records
  176. * associated with $descendantModel->$descendantId record
  177. */
  178. public function whereDescendantId($descendantRecordModel, $descendantRecordId, $model)
  179. {
  180. if(!$module = self::$moduleManager->getModuleByModel($model))
  181. {
  182. throw new dmException(sprintf('No module %s', $model));
  183. }
  184. if($descendantRecordModel == $model)
  185. {
  186. return $this->addWhere($this->getRootAlias().'.id = ?', $descendantRecordId);
  187. }
  188. if(!$descendantModule = $module->getDescendant($descendantRecordModel))
  189. {
  190. throw new dmRecordException(sprintf('%s is not an descendant of %s', $descendantRecordModel, $module));
  191. }
  192. $parent = $module;
  193. $parentAlias = $this->getRootAlias();
  194. foreach($descendantModule->getPathFrom($module, true) as $descendantKey => $descendant)
  195. {
  196. if ($descendantKey != $module->getKey())
  197. {
  198. if (!$relation = $parent->getTable()->getRelationHolder()->getByClass($descendant->getModel()))
  199. {
  200. throw new dmRecordException(sprintf('%s has no relation for class %s', $parent, $descendant->getModel()));
  201. }
  202. $this->leftJoin($parentAlias.'.'.$relation['alias'].' '.$descendantKey);
  203. if ($descendant->is($module))
  204. {
  205. break;
  206. }
  207. $parent = $descendant;
  208. $parentAlias = $descendantKey;
  209. }
  210. }
  211. $this->addWhere($descendantModule->getKey().'.id = ?', $descendantRecordId);
  212. return $this;
  213. }
  214. /**
  215. * Add asc order by position field
  216. * if $model is specified, will verify that it has I18n
  217. * @return myDoctrineQuery $this
  218. */
  219. public function orderByPosition($model = null)
  220. {
  221. if (null !== $model)
  222. {
  223. if (!dmDb::table($model)->hasField('position'))
  224. {
  225. return $this;
  226. }
  227. }
  228. $me = $this->getRootAlias();
  229. return $this
  230. ->addOrderBy("$me.position asc");
  231. }
  232. /**
  233. * returns join alias for a given relation alias, if joined
  234. * ex: "Elem e, e.Categ my_categ"
  235. * alias for joined relation Categ = my_categ
  236. * getJoinAliasForRelationAlias('Elem', 'Categ') ->my_categ
  237. */
  238. public function getJoinAliasForRelationAlias($model, $relationAlias)
  239. {
  240. $this->buildSqlQuery();
  241. foreach ($this->getQueryComponents() as $joinAlias => $queryComponent)
  242. {
  243. if (
  244. isset($queryComponent['relation'])
  245. && $relationAlias == $queryComponent['relation']['alias']
  246. && $model == $queryComponent['relation']['localTable']->getComponentName()
  247. )
  248. {
  249. return $joinAlias;
  250. }
  251. }
  252. return null;
  253. }
  254. /**
  255. * @return myDoctrineCollection|null the fetched collection
  256. */
  257. public function fetchRecords($params = array())
  258. {
  259. return $this->execute($params, Doctrine_Core::HYDRATE_RECORD);
  260. }
  261. /**
  262. * Add limit(1) to the query,
  263. * then execute $this->fetchOne()
  264. * @return myDoctrineRecord|null the fetched record
  265. */
  266. public function fetchRecord($params = array(), $hydrationMode = Doctrine_Core::HYDRATE_RECORD)
  267. {
  268. return $this->limit(1)->fetchOne($params, $hydrationMode);
  269. }
  270. public function fetchValue($params = array())
  271. {
  272. return $this->execute($params, Doctrine_Core::HYDRATE_SINGLE_SCALAR);
  273. }
  274. public function fetchValues($params = array())
  275. {
  276. return $this->execute($params, Doctrine_Core::HYDRATE_SCALAR);
  277. }
  278. public function fetchOneArray($params = array())
  279. {
  280. return $this->fetchOne($params, Doctrine_Core::HYDRATE_ARRAY);
  281. }
  282. /**
  283. * fetch brutal PDO array with numeric keys
  284. * @return array PDO result
  285. */
  286. public function fetchPDO($params = array())
  287. {
  288. return $this->execute($params, Doctrine_Core::HYDRATE_NONE);
  289. }
  290. /**
  291. * fetch brutal flat array with numeric keys
  292. * @return array PDO result
  293. */
  294. public function fetchFlat($params = array())
  295. {
  296. return $this->execute($params, 'dmFlat');
  297. }
  298. public function exists()
  299. {
  300. return $this->count() > 0;
  301. }
  302. public function toDebug()
  303. {
  304. return $this->getSqlQuery();
  305. }
  306. public static function setModuleManager(dmModuleManager $moduleManager)
  307. {
  308. self::$moduleManager = $moduleManager;
  309. }
  310. /**
  311. *
  312. * @return dmDoctrineQuery
  313. */
  314. public function andWhere($where, $params = array())
  315. {
  316. return parent::andWhere($where, $params);
  317. }
  318. }