5 use Doctrine\DBAL\Query\Expression\CompositeExpression;
26 public function calculate($function, $property, $property_type =
null) {
28 throw new DomainException(
"'{$function}' is not a valid numeric function");
31 if (!isset($property_type)) {
33 $property_type =
'attribute';
35 $property_type =
'metadata';
43 switch ($property_type) {
49 $alias = $select->joinEntitiesTable($select->getTableAlias(), $join_column,
'inner',
'e');
50 $select->select(
"{$function}({$alias}.{$property}) AS calculation");
55 if (!empty($this->options->annotation_name_value_pairs) && $this->options->annotation_name_value_pairs[0]->names != $property) {
56 $alias = $select->joinAnnotationTable($select->getTableAlias(), $join_column, $property);
59 $select->select(
"{$function}({$alias}.value) AS calculation");
63 $alias = $select->joinMetadataTable($select->getTableAlias(), $join_column, $property);
64 $select->select(
"{$function}({$alias}.value) AS calculation");
81 $count_expr = $this->options->distinct ?
"DISTINCT {$select->getTableAlias()}.id" :
'*';
82 $select->select(
"COUNT({$count_expr}) AS total");
98 if ($this->options->annotation_calculation) {
99 $clauses = $this->options->annotation_name_value_pairs;
100 if (
count($clauses) > 1 && $this->options->annotation_name_value_pairs_operator !==
'OR') {
101 throw new LogicException(
'Annotation calculation can not be performed on multiple annotation name value pairs merged with AND');
104 $clause = array_shift($clauses);
106 return $this->
calculate($this->options->annotation_calculation, $clause->names,
'annotation');
107 }
elseif ($this->options->metadata_calculation) {
108 $clauses = $this->options->metadata_name_value_pairs;
109 if (
count($clauses) > 1 && $this->options->metadata_name_value_pairs_operator !==
'OR') {
110 throw new LogicException(
'Metadata calculation can not be performed on multiple metadata name value pairs merged with AND');
113 $clause = array_shift($clauses);
115 return $this->
calculate($this->options->metadata_calculation, $clause->names,
'metadata');
116 }
elseif ($this->options->count) {
117 return $this->
count();
118 }
elseif ($this->options->batch) {
119 return $this->
batch($this->options->limit, $this->options->offset, $this->options->callback);
121 return $this->
get($this->options->limit, $this->options->offset, $this->options->callback);
131 $distinct = $this->options->distinct ?
'DISTINCT ' :
'';
132 $select->select(
"{$distinct}{$select->getTableAlias()}.*");
134 $this->
expandInto($select, $select->getTableAlias());
139 $original_order =
elgg_extract(
'order_by', $this->options->__original_options);
140 if (empty($this->options->order_by) && $original_order !==
false) {
141 $select->addOrderBy(
"{$select->getTableAlias()}.time_created",
'desc');
142 $select->addOrderBy(
"{$select->getTableAlias()}.id",
'desc');
146 $select->setMaxResults((
int)
$limit);
147 $select->setFirstResult((
int)
$offset);
150 $callback = $callback ?: $this->options->callback;
151 if (!isset($callback)) {
152 $callback =
function ($row) {
153 return new \ElggRelationship($row);
159 $preload = array_filter(
$results,
function($e) {
160 return $e instanceof \ElggRelationship;
182 foreach ($this->options->joins as $join) {
183 $join->prepare(
$qb,
$qb->getTableAlias());
186 foreach ($this->options->wheres as $where) {
187 $ands[] = $where->prepare(
$qb,
$qb->getTableAlias());
191 $ands[] = $this->
buildPairedMetadataClause($qb, $this->options->metadata_name_value_pairs, $this->options->metadata_name_value_pairs_operator);
193 $ands[] = $this->
buildPairedAnnotationClause($qb, $this->options->annotation_name_value_pairs, $this->options->annotation_name_value_pairs_operator);
196 $ands =
$qb->merge($ands);
198 $qb->andWhere($ands);
213 $joined_alias =
$qb->joinEntitiesTable(
$qb->getTableAlias(), $this->getJoinColumn(),
'inner',
'e');
214 return EntityWhereClause::factory($this->options)->prepare(
$qb, $joined_alias);
232 foreach ($clauses as $clause) {
234 if (strtoupper($boolean) ===
'OR' ||
count($clauses) === 1) {
235 $joined_alias =
$qb->joinMetadataTable(
$qb->getTableAlias(), $join_column,
null,
'inner',
'md');
237 $joined_alias =
$qb->joinMetadataTable(
$qb->getTableAlias(), $join_column, $clause->names);
240 $parts[] = $clause->prepare(
$qb, $joined_alias);
244 return $qb->merge($parts, $boolean);
262 foreach ($clauses as $clause) {
263 if (strtoupper($boolean) ===
'OR' ||
count($clauses) === 1) {
266 $joined_alias =
$qb->joinAnnotationTable(
$qb->getTableAlias(), $join_column, $clause->names);
269 $parts[] = $clause->prepare(
$qb, $joined_alias);
272 return $qb->merge($parts, $boolean);
287 foreach ($clauses as $clause) {
288 $parts[] = $clause->prepare(
$qb,
$qb->getTableAlias());
291 return $qb->merge($parts, $boolean);
300 if (!empty($this->options->inverse_relationship)) {
Builds queries for matching annotations against their properties.
Builds queries for filtering entities by their properties in the entities table.
Builds clauses for filtering entities by their properties in entity_relationships table.
Database abstraction query builder.
Relationships repository contains methods for fetching relationships from database or performing calc...
buildQuery(QueryBuilder $qb)
Build a database query.
buildPairedRelationshipClause(QueryBuilder $qb, $clauses, $boolean='AND')
Process relationship pairs.
buildPairedAnnotationClause(QueryBuilder $qb, $clauses, $boolean='AND')
Process annotation name value pairs Joins the annotation table on guid_one|guid_two in relationships ...
buildPairedMetadataClause(QueryBuilder $qb, $clauses, $boolean='AND')
Process metadata name value pairs Joins the metadata table on guid_one|guid_two in relationships tabl...
calculate($function, $property, $property_type=null)
Apply numeric calculation to a column.Calculation, e.g. max, min, avg Property name Property typeint|...
getJoinColumn()
Return the base column to use in joins.
execute()
Apply correct execution method based on calculation, count or other criteria.mixed
buildEntityClause(QueryBuilder $qb)
Process entity attribute wheres Joins entities table on guid_one|guid_two in relationships table and ...
Abstract methods for interfacing with the database.
expandInto(QueryBuilder $qb, $table_alias=null)
Extend query builder with select, group_by, having and order_by clauses from $options.
batch($limit=null, $offset=null, $callback=null)
Fetch rows as an ElggBatch.
static fromTable(string $table, ?string $alias=null)
Returns a QueryBuilder for selecting data from a given table.
Exception thrown if a value does not adhere to a defined valid data domain.
Exception that represents error in the program logic.
if($item instanceof \ElggEntity) elseif($item instanceof \ElggRiverItem) elseif($item instanceof \ElggRelationship) elseif(is_callable([ $item, 'getType']))
_elgg_services()
Get the global service provider.
elgg_extract($key, $array, $default=null, bool $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.