PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/core/lib/Drupal/Core/Entity/Query/QueryBase.php

https://gitlab.com/reasonat/test8
PHP | 486 lines | 214 code | 59 blank | 213 comment | 13 complexity | 6626447a1ef86256e60d4774f6d79ddb MD5 | raw file
  1. <?php
  2. namespace Drupal\Core\Entity\Query;
  3. use Drupal\Core\Database\Query\PagerSelectExtender;
  4. use Drupal\Core\Entity\EntityTypeInterface;
  5. /**
  6. * The base entity query class.
  7. */
  8. abstract class QueryBase implements QueryInterface {
  9. /**
  10. * The entity type this query runs against.
  11. *
  12. * @var string
  13. */
  14. protected $entityTypeId;
  15. /**
  16. * Information about the entity type.
  17. *
  18. * @var \Drupal\Core\Entity\EntityTypeInterface
  19. */
  20. protected $entityType;
  21. /**
  22. * The list of sorts.
  23. *
  24. * @var array
  25. */
  26. protected $sort = array();
  27. /**
  28. * TRUE if this is a count query, FALSE if it isn't.
  29. *
  30. * @var bool
  31. */
  32. protected $count = FALSE;
  33. /**
  34. * Conditions.
  35. *
  36. * @var \Drupal\Core\Entity\Query\ConditionInterface
  37. */
  38. protected $condition;
  39. /**
  40. * The list of aggregate expressions.
  41. *
  42. * @var array
  43. */
  44. protected $aggregate = array();
  45. /**
  46. * The list of columns to group on.
  47. *
  48. * @var array
  49. */
  50. protected $groupBy = array();
  51. /**
  52. * Aggregate Conditions
  53. *
  54. * @var \Drupal\Core\Entity\Query\ConditionAggregateInterface
  55. */
  56. protected $conditionAggregate;
  57. /**
  58. * The list of sorts over the aggregate results.
  59. *
  60. * @var array
  61. */
  62. protected $sortAggregate = array();
  63. /**
  64. * The query range.
  65. *
  66. * @var array
  67. */
  68. protected $range = array();
  69. /**
  70. * The query metadata for alter purposes.
  71. *
  72. * @var array
  73. */
  74. protected $alterMetaData;
  75. /**
  76. * The query tags.
  77. *
  78. * @var array
  79. */
  80. protected $alterTags;
  81. /**
  82. * Whether access check is requested or not. Defaults to TRUE.
  83. *
  84. * @var bool
  85. */
  86. protected $accessCheck = TRUE;
  87. /**
  88. * Flag indicating whether to query the current revision or all revisions.
  89. *
  90. * @var bool
  91. */
  92. protected $allRevisions = FALSE;
  93. /**
  94. * The query pager data.
  95. *
  96. * @var array
  97. *
  98. * @see Query::pager()
  99. */
  100. protected $pager = array();
  101. /**
  102. * List of potential namespaces of the classes belonging to this query.
  103. *
  104. * @var array
  105. */
  106. protected $namespaces = array();
  107. /**
  108. * Constructs this object.
  109. *
  110. * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
  111. * The entity type definition.
  112. * @param string $conjunction
  113. * - AND: all of the conditions on the query need to match.
  114. * - OR: at least one of the conditions on the query need to match.
  115. * @param array $namespaces
  116. * List of potential namespaces of the classes belonging to this query.
  117. */
  118. public function __construct(EntityTypeInterface $entity_type, $conjunction, array $namespaces) {
  119. $this->entityTypeId = $entity_type->id();
  120. $this->entityType = $entity_type;
  121. $this->conjunction = $conjunction;
  122. $this->namespaces = $namespaces;
  123. $this->condition = $this->conditionGroupFactory($conjunction);
  124. if ($this instanceof QueryAggregateInterface) {
  125. $this->conditionAggregate = $this->conditionAggregateGroupFactory($conjunction);
  126. }
  127. }
  128. /**
  129. * {@inheritdoc}
  130. */
  131. public function getEntityTypeId() {
  132. return $this->entityTypeId;
  133. }
  134. /**
  135. * {@inheritdoc}
  136. */
  137. public function condition($property, $value = NULL, $operator = NULL, $langcode = NULL) {
  138. $this->condition->condition($property, $value, $operator, $langcode);
  139. return $this;
  140. }
  141. /**
  142. * {@inheritdoc}
  143. */
  144. public function exists($property, $langcode = NULL) {
  145. $this->condition->exists($property, $langcode);
  146. return $this;
  147. }
  148. /**
  149. * {@inheritdoc}
  150. */
  151. public function notExists($property, $langcode = NULL) {
  152. $this->condition->notExists($property, $langcode);
  153. return $this;
  154. }
  155. /**
  156. * {@inheritdoc}
  157. */
  158. public function range($start = NULL, $length = NULL) {
  159. $this->range = array(
  160. 'start' => $start,
  161. 'length' => $length,
  162. );
  163. return $this;
  164. }
  165. /**
  166. * Creates an object holding a group of conditions.
  167. *
  168. * See andConditionGroup() and orConditionGroup() for more.
  169. *
  170. * @param string $conjunction
  171. * - AND (default): this is the equivalent of andConditionGroup().
  172. * - OR: this is the equivalent of orConditionGroup().
  173. *
  174. * @return \Drupal\Core\Entity\Query\ConditionInterface
  175. * An object holding a group of conditions.
  176. */
  177. protected function conditionGroupFactory($conjunction = 'AND') {
  178. $class = static::getClass($this->namespaces, 'Condition');
  179. return new $class($conjunction, $this, $this->namespaces);
  180. }
  181. /**
  182. * {@inheritdoc}
  183. */
  184. public function andConditionGroup() {
  185. return $this->conditionGroupFactory('and');
  186. }
  187. /**
  188. * {@inheritdoc}
  189. */
  190. public function orConditionGroup() {
  191. return $this->conditionGroupFactory('or');
  192. }
  193. /**
  194. * {@inheritdoc}
  195. */
  196. public function sort($field, $direction = 'ASC', $langcode = NULL) {
  197. $this->sort[] = array(
  198. 'field' => $field,
  199. 'direction' => strtoupper($direction),
  200. 'langcode' => $langcode,
  201. );
  202. return $this;
  203. }
  204. /**
  205. * {@inheritdoc}
  206. */
  207. public function count() {
  208. $this->count = TRUE;
  209. return $this;
  210. }
  211. /**
  212. * {@inheritdoc}
  213. */
  214. public function accessCheck($access_check = TRUE) {
  215. $this->accessCheck = $access_check;
  216. return $this;
  217. }
  218. /**
  219. * {@inheritdoc}
  220. */
  221. public function currentRevision() {
  222. $this->allRevisions = FALSE;
  223. return $this;
  224. }
  225. /**
  226. * {@inheritdoc}
  227. */
  228. public function allRevisions() {
  229. $this->allRevisions = TRUE;
  230. return $this;
  231. }
  232. /**
  233. * {@inheritdoc}
  234. */
  235. public function pager($limit = 10, $element = NULL) {
  236. // Even when not using SQL, storing the element PagerSelectExtender is as
  237. // good as anywhere else.
  238. if (!isset($element)) {
  239. $element = PagerSelectExtender::$maxElement++;
  240. }
  241. elseif ($element >= PagerSelectExtender::$maxElement) {
  242. PagerSelectExtender::$maxElement = $element + 1;
  243. }
  244. $this->pager = array(
  245. 'limit' => $limit,
  246. 'element' => $element,
  247. );
  248. return $this;
  249. }
  250. /**
  251. * Gets the total number of results and initialize a pager for the query.
  252. *
  253. * The pager can be disabled by either setting the pager limit to 0, or by
  254. * setting this query to be a count query.
  255. */
  256. protected function initializePager() {
  257. if ($this->pager && !empty($this->pager['limit']) && !$this->count) {
  258. $page = pager_find_page($this->pager['element']);
  259. $count_query = clone $this;
  260. $this->pager['total'] = $count_query->count()->execute();
  261. $this->pager['start'] = $page * $this->pager['limit'];
  262. pager_default_initialize($this->pager['total'], $this->pager['limit'], $this->pager['element']);
  263. $this->range($this->pager['start'], $this->pager['limit']);
  264. }
  265. }
  266. /**
  267. * {@inheritdoc}
  268. */
  269. public function tableSort(&$headers) {
  270. // If 'field' is not initialized, the header columns aren't clickable.
  271. foreach ($headers as $key => $header) {
  272. if (is_array($header) && isset($header['specifier'])) {
  273. $headers[$key]['field'] = '';
  274. }
  275. }
  276. $order = tablesort_get_order($headers);
  277. $direction = tablesort_get_sort($headers);
  278. foreach ($headers as $header) {
  279. if (is_array($header) && ($header['data'] == $order['name'])) {
  280. $this->sort($header['specifier'], $direction, isset($header['langcode']) ? $header['langcode'] : NULL);
  281. }
  282. }
  283. return $this;
  284. }
  285. /**
  286. * Makes sure that the Condition object is cloned as well.
  287. */
  288. function __clone() {
  289. $this->condition = clone $this->condition;
  290. }
  291. /**
  292. * {@inheritdoc}
  293. */
  294. public function addTag($tag) {
  295. $this->alterTags[$tag] = 1;
  296. return $this;
  297. }
  298. /**
  299. * {@inheritdoc}
  300. */
  301. public function hasTag($tag) {
  302. return isset($this->alterTags[$tag]);
  303. }
  304. /**
  305. * {@inheritdoc}
  306. */
  307. public function hasAllTags() {
  308. return !(boolean)array_diff(func_get_args(), array_keys($this->alterTags));
  309. }
  310. /**
  311. * {@inheritdoc}
  312. */
  313. public function hasAnyTag() {
  314. return (boolean)array_intersect(func_get_args(), array_keys($this->alterTags));
  315. }
  316. /**
  317. * {@inheritdoc}
  318. */
  319. public function addMetaData($key, $object) {
  320. $this->alterMetaData[$key] = $object;
  321. return $this;
  322. }
  323. /**
  324. * {@inheritdoc}
  325. */
  326. public function getMetaData($key) {
  327. return isset($this->alterMetaData[$key]) ? $this->alterMetaData[$key] : NULL;
  328. }
  329. /**
  330. * {@inheritdoc}
  331. */
  332. public function aggregate($field, $function, $langcode = NULL, &$alias = NULL) {
  333. if (!isset($alias)) {
  334. $alias = $this->getAggregationAlias($field, $function);
  335. }
  336. $this->aggregate[$alias] = array(
  337. 'field' => $field,
  338. 'function' => $function,
  339. 'alias' => $alias,
  340. 'langcode' => $langcode,
  341. );
  342. return $this;
  343. }
  344. /**
  345. * {@inheritdoc}
  346. */
  347. public function conditionAggregate($field, $function = NULL, $value = NULL, $operator = '=', $langcode = NULL) {
  348. $this->aggregate($field, $function, $langcode);
  349. $this->conditionAggregate->condition($field, $function, $value, $operator, $langcode);
  350. return $this;
  351. }
  352. /**
  353. * {@inheritdoc}
  354. */
  355. public function sortAggregate($field, $function, $direction = 'ASC', $langcode = NULL) {
  356. $alias = $this->getAggregationAlias($field, $function);
  357. $this->sortAggregate[$alias] = array(
  358. 'field' => $field,
  359. 'function' => $function,
  360. 'direction' => $direction,
  361. 'langcode' => $langcode,
  362. );
  363. $this->aggregate($field, $function, $langcode, $alias);
  364. return $this;
  365. }
  366. /**
  367. * {@inheritdoc}
  368. */
  369. public function groupBy($field, $langcode = NULL) {
  370. $this->groupBy[] = array(
  371. 'field' => $field,
  372. 'langcode' => $langcode,
  373. );
  374. return $this;
  375. }
  376. /**
  377. * Generates an alias for a field and it's aggregated function.
  378. *
  379. * @param string $field
  380. * The field name used in the alias.
  381. * @param string $function
  382. * The aggregation function used in the alias.
  383. *
  384. * @return string
  385. * The alias for the field.
  386. */
  387. protected function getAggregationAlias($field, $function) {
  388. return strtolower($field . '_' . $function);
  389. }
  390. /**
  391. * Gets a list of namespaces of the ancestors of a class.
  392. *
  393. * @param $object
  394. * An object within a namespace.
  395. *
  396. * @return array
  397. * A list containing the namespace of the class, the namespace of the
  398. * parent of the class and so on and so on.
  399. */
  400. public static function getNamespaces($object) {
  401. $namespaces = array();
  402. for ($class = get_class($object); $class; $class = get_parent_class($class)) {
  403. $namespaces[] = substr($class, 0, strrpos($class, '\\'));
  404. }
  405. return $namespaces;
  406. }
  407. /**
  408. * Finds a class in a list of namespaces.
  409. *
  410. * @param array $namespaces
  411. * A list of namespaces.
  412. * @param string $short_class_name
  413. * A class name without namespace.
  414. *
  415. * @return string
  416. * The fully qualified name of the class.
  417. */
  418. public static function getClass(array $namespaces, $short_class_name) {
  419. foreach ($namespaces as $namespace) {
  420. $class = $namespace . '\\' . $short_class_name;
  421. if (class_exists($class)) {
  422. return $class;
  423. }
  424. }
  425. }
  426. }