From c8881c89e3b334498eeb5196846bac3ae44cc8bd Mon Sep 17 00:00:00 2001 From: ura soul Date: Tue, 31 May 2016 14:43:57 +0100 Subject: [PATCH] fix(river): optional joins now added to river and metastring queries after default joins to allow default joins to be referenced by optional joins. 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 --- engine/lib/metastrings.php | 21 ++++++++++++--------- engine/lib/river.php | 31 +++++++++++++++++++------------ 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php index 4b12adfc445..faa3975bbe9 100644 --- a/engine/lib/metastrings.php +++ b/engine/lib/metastrings.php @@ -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); diff --git a/engine/lib/river.php b/engine/lib/river.php index b56acd481d3..9dd450d7c3e 100644 --- a/engine/lib/river.php +++ b/engine/lib/river.php @@ -341,7 +341,7 @@ 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'"; } @@ -349,7 +349,11 @@ function elgg_get_river(array $options = array()) { $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,7 +767,7 @@ 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 @@ -768,18 +775,18 @@ function _elgg_river_test($hook, $type, $value) { * @access private */ function _elgg_river_disable($event, $type, $entity) { - + if (!elgg_instanceof($entity)) { return true; } - + $dbprefix = elgg_get_config('dbprefix'); $query = <<guid} OR rv.object_guid = {$entity->guid} OR rv.target_guid = {$entity->guid}); QUERY; - + update_data($query); return true; } @@ -787,7 +794,7 @@ function _elgg_river_disable($event, $type, $entity) { /** * 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 @@ -795,11 +802,11 @@ function _elgg_river_disable($event, $type, $entity) { * @access private */ function _elgg_river_enable($event, $type, $entity) { - + if (!elgg_instanceof($entity)) { return true; } - + $dbprefix = elgg_get_config('dbprefix'); $query = <<guid} OR oe.guid = {$entity->guid} OR te.guid = {$entity->guid}); QUERY;