Permalink
Browse files

fix(river): custom joins can now reference default joined tables.

When building more complex queries there may be a need to reference table aliases introduced
by the default joins in _elgg_get_metastring_based_objects and elgg_get_river. This fix ensures
that the default join table aliases are available when defining custom joins
- which is a requirement for building effective and efficient queries.

Fixes #8580
  • Loading branch information...
ura soul
ura soul committed May 31, 2016
1 parent aa1cb04 commit a6590a9a68f534b8ae6bde274bf642bec301f4a3
Showing with 31 additions and 21 deletions.
  1. +12 −9 engine/lib/metastrings.php
  2. +19 −12 engine/lib/river.php
View
@@ -215,7 +215,7 @@ function _elgg_get_metastring_based_objects($options) {
$options['joins'] = array($options['joins']);
}
$joins = $options['joins'];
$joins = array();
$joins[] = "JOIN {$db_prefix}entities e ON n_table.entity_guid = e.guid";
// evaluate selects
@@ -232,7 +232,7 @@ function _elgg_get_metastring_based_objects($options) {
$custom_callback = ($options['callback'] == 'row_to_elggmetadata'
|| $options['callback'] == 'row_to_elggannotation');
$is_calculation = $options['metastring_calculation'] ? true : false;
if ($custom_callback || $is_calculation) {
$joins[] = "JOIN {$db_prefix}metastrings n on n_table.name_id = n.id";
$joins[] = "JOIN {$db_prefix}metastrings v on n_table.value_id = v.id";
@@ -241,13 +241,8 @@ function _elgg_get_metastring_based_objects($options) {
$selects[] = 'v.string as value';
}
foreach ($joins as $i => $join) {
if ($join === false) {
return false;
} elseif (empty($join)) {
unset($joins[$i]);
}
}
// add optional joins
$joins = array_merge($joins, $options['joins']);
// metastrings
$metastring_clauses = _elgg_get_metastring_sql('n_table', $options['metastring_names'],
@@ -284,6 +279,14 @@ function _elgg_get_metastring_based_objects($options) {
$query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table";
}
foreach ($joins as $i => $join) {
if ($join === false) {
return false;
} elseif (empty($join)) {
unset($joins[$i]);
}
}
// remove identical join clauses
$joins = array_unique($joins);
View
@@ -341,15 +341,19 @@ function elgg_get_river(array $options = array()) {
if ($options['posted_time_upper'] && is_int($options['posted_time_upper'])) {
$wheres[] = "rv.posted <= {$options['posted_time_upper']}";
}
if (!access_get_show_hidden_status()) {
$wheres[] = "rv.enabled = 'yes'";
}
$joins = $options['joins'];
$dbprefix = elgg_get_config('dbprefix');
// joins
$joins = array();
$joins[] = "JOIN {$dbprefix}entities oe ON rv.object_guid = oe.guid";
// LEFT JOIN is used because all river items do not necessarily have target
$joins[] = "LEFT JOIN {$dbprefix}entities te ON rv.target_guid = te.guid";
@@ -365,6 +369,9 @@ function elgg_get_river(array $options = array()) {
}
}
// add optional joins
$joins = array_merge($joins, $options['joins']);
// see if any functions failed
// remove empty strings on successful functions
foreach ($wheres as $i => $where) {
@@ -380,12 +387,12 @@ function elgg_get_river(array $options = array()) {
if (!$options['count']) {
$distinct = $options['distinct'] ? "DISTINCT" : "";
$query = "SELECT $distinct rv.* FROM {$CONFIG->dbprefix}river rv ";
} else {
// note: when DISTINCT unneeded, it's slightly faster to compute COUNT(*) than IDs
$count_expr = $options['distinct'] ? "DISTINCT rv.id" : "*";
$query = "SELECT COUNT($count_expr) as total FROM {$CONFIG->dbprefix}river rv ";
}
@@ -760,46 +767,46 @@ function _elgg_river_test($hook, $type, $value) {
/**
* Disable river entries that reference a disabled entity as subject/object/target
*
*
* @param string $event The event 'disable'
* @param string $type Type of entity being disabled 'all'
* @param mixed $entity The entity being disabled
* @return boolean
* @access private
*/
function _elgg_river_disable($event, $type, $entity) {
if (!elgg_instanceof($entity)) {
return true;
}
$dbprefix = elgg_get_config('dbprefix');
$query = <<<QUERY
UPDATE {$dbprefix}river AS rv
SET rv.enabled = 'no'
WHERE (rv.subject_guid = {$entity->guid} OR rv.object_guid = {$entity->guid} OR rv.target_guid = {$entity->guid});
QUERY;
update_data($query);
return true;
}
/**
* Enable river entries that reference a re-enabled entity as subject/object/target
*
*
* @param string $event The event 'enable'
* @param string $type Type of entity being enabled 'all'
* @param mixed $entity The entity being enabled
* @return boolean
* @access private
*/
function _elgg_river_enable($event, $type, $entity) {
if (!elgg_instanceof($entity)) {
return true;
}
$dbprefix = elgg_get_config('dbprefix');
$query = <<<QUERY
UPDATE {$dbprefix}river AS rv
@@ -808,9 +815,9 @@ function _elgg_river_enable($event, $type, $entity) {
LEFT JOIN {$dbprefix}entities AS te ON te.guid = rv.target_guid
SET rv.enabled = 'yes'
WHERE (
(se.enabled = 'yes' OR se.guid IS NULL) AND
(se.enabled = 'yes' OR se.guid IS NULL) AND
(oe.enabled = 'yes' OR oe.guid IS NULL) AND
(te.enabled = 'yes' OR te.guid IS NULL)
(te.enabled = 'yes' OR te.guid IS NULL)
)
AND (se.guid = {$entity->guid} OR oe.guid = {$entity->guid} OR te.guid = {$entity->guid});
QUERY;

0 comments on commit a6590a9

Please sign in to comment.