예제 #1
0
/**
 * Listen to the creation of metadata
 *
 * @param string       $event    the name of the event
 * @param string       $type     the type of the event
 * @param ElggMetadata $metadata supplied metadata
 *
 * @return void
 */
function tag_tools_create_metadata_event_handler($event, $type, $metadata)
{
    if (empty($metadata) || !$metadata instanceof ElggMetadata) {
        return;
    }
    // is it a tag
    if ($metadata->name != 'tags') {
        return;
    }
    // get the entity for further use
    $ia = elgg_set_ignore_access(true);
    $entity_guid = $metadata->entity_guid;
    // can't use elgg get entity because cache is not correctly updated
    $entity_row = get_entity_as_row($entity_guid);
    elgg_set_ignore_access($ia);
    // shortcut for private entities
    if ($entity_row->access_id == ACCESS_PRIVATE) {
        return;
    }
    // only send notifications on creation of the entity
    $time_created_treshold = 5;
    if ($entity_row->time_created < time() - $time_created_treshold) {
        // assume it is an update
        return;
    }
    // check of the entity is allowed for notifications
    if (!tag_tools_is_notification_entity($entity_row->guid)) {
        return;
    }
    $tag = $metadata->value;
    $options = ['type' => 'user', 'annotation_name_value_pairs' => ['name' => 'follow_tag', 'value' => $tag], 'limit' => false];
    $ia = elgg_set_ignore_access(true);
    $dbprefix = elgg_get_config('dbprefix');
    $entities = new ElggBatch('elgg_get_entities_from_annotations', $options);
    foreach ($entities as $user) {
        // check if not trying to notify the owner
        if ($user->getGUID() == $entity_row->owner_guid) {
            continue;
        }
        // force a correct access bit
        elgg_set_ignore_access(false);
        // check access for the user, can't use has_access_to_entity
        // because that requires a full entity
        $access_bit = _elgg_get_access_where_sql(['user_guid' => $user->getGUID()]);
        // ignore access to get the correct next user
        elgg_set_ignore_access(true);
        // build correct query to check access
        $query = "SELECT guid FROM {$dbprefix}entities e\n\t\t\t WHERE e.guid = {$entity_guid}\n\t\t\t AND {$access_bit}";
        if (get_data($query)) {
            // regsiter shutdown function because we need the full entity
            // this is a workaround and should be reviewed in the near future
            register_shutdown_function('tag_tools_notify_user', $user->getGUID(), $entity_row->guid, $tag);
        }
    }
    elgg_set_ignore_access($ia);
}
/**
 * Return the number of users registered in the system.
 *
 * @param bool $show_deactivated Count not enabled users?
 *
 * @return int
 */
function get_number_users($show_deactivated = false)
{
    global $CONFIG;
    $access = "";
    if (!$show_deactivated) {
        $access = "and " . _elgg_get_access_where_sql(array('table_alias' => ''));
    }
    $query = "SELECT count(*) as count\n\t\tfrom {$CONFIG->dbprefix}entities where type='user' {$access}";
    $result = get_data_row($query);
    if ($result) {
        return $result->count;
    }
    return false;
}
예제 #3
0
/**
 * Get an array of users from an email address
 *
 * @param string $email Email address.
 *
 * @return array
 */
function get_user_by_email($email)
{
    global $CONFIG;
    $email = sanitise_string($email);
    $access = _elgg_get_access_where_sql();
    $query = "SELECT e.* FROM {$CONFIG->dbprefix}entities e\n\t\tJOIN {$CONFIG->dbprefix}users_entity u ON e.guid = u.guid\n\t\tWHERE email = '{$email}' AND {$access}";
    return get_data($query, 'entity_row_to_elggstar');
}
예제 #4
0
function elgg_solr_get_entity_guids(array $options = array())
{
    global $CONFIG;
    $defaults = array('types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'guids' => ELGG_ENTITIES_ANY_VALUE, 'owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'container_guids' => ELGG_ENTITIES_ANY_VALUE, 'site_guids' => $CONFIG->site_guid, 'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'reverse_order_by' => false, 'order_by' => 'e.time_created desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'limit' => 10, 'offset' => 0, 'count' => false, 'selects' => array(), 'wheres' => array(), 'joins' => array(), 'callback' => false, '__ElggBatch' => null);
    $options = array_merge($defaults, $options);
    // can't use helper function with type_subtype_pair because
    // it's already an array...just need to merge it
    if (isset($options['type_subtype_pair'])) {
        if (isset($options['type_subtype_pairs'])) {
            $options['type_subtype_pairs'] = array_merge($options['type_subtype_pairs'], $options['type_subtype_pair']);
        } else {
            $options['type_subtype_pairs'] = $options['type_subtype_pair'];
        }
    }
    $singulars = array('type', 'subtype', 'guid', 'owner_guid', 'container_guid', 'site_guid');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    // evaluate where clauses
    if (!is_array($options['wheres'])) {
        $options['wheres'] = array($options['wheres']);
    }
    $wheres = $options['wheres'];
    $wheres[] = _elgg_get_entity_type_subtype_where_sql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.guid', $options['guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']);
    $wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']);
    // see if any functions failed
    // remove empty strings on successful functions
    foreach ($wheres as $i => $where) {
        if ($where === false) {
            return false;
        } elseif (empty($where)) {
            unset($wheres[$i]);
        }
    }
    // remove identical where clauses
    $wheres = array_unique($wheres);
    // evaluate join clauses
    if (!is_array($options['joins'])) {
        $options['joins'] = array($options['joins']);
    }
    // remove identical join clauses
    $joins = array_unique($options['joins']);
    foreach ($joins as $i => $join) {
        if ($join === false) {
            return false;
        } elseif (empty($join)) {
            unset($joins[$i]);
        }
    }
    // evalutate selects
    if ($options['selects']) {
        $selects = '';
        foreach ($options['selects'] as $select) {
            $selects .= ", {$select}";
        }
    } else {
        $selects = '';
    }
    if (!$options['count']) {
        $distinct = '';
        if ($options['require_distinct']) {
            $distinct = ' DISTINCT';
        }
        $query = "SELECT{$distinct} e.guid{$selects} FROM {$CONFIG->dbprefix}entities e ";
    } else {
        $query = "SELECT count(DISTINCT e.guid) as total FROM {$CONFIG->dbprefix}entities e ";
    }
    // add joins
    foreach ($joins as $j) {
        $query .= " {$j} ";
    }
    // add wheres
    $query .= ' WHERE ';
    foreach ($wheres as $w) {
        $query .= " {$w} AND ";
    }
    // Add access controls
    $query .= _elgg_get_access_where_sql();
    // reverse order by
    if ($options['reverse_order_by']) {
        $options['order_by'] = _elgg_sql_reverse_order_by_clause($options['order_by']);
    }
    if (!$options['count']) {
        if ($options['group_by']) {
            $query .= " GROUP BY {$options['group_by']}";
        }
        if ($options['order_by']) {
            $query .= " ORDER BY {$options['order_by']}";
        }
        if ($options['limit']) {
            $limit = sanitise_int($options['limit'], false);
            $offset = sanitise_int($options['offset'], false);
            $query .= " LIMIT {$offset}, {$limit}";
        }
        if ($options['callback'] === 'entity_row_to_elggstar') {
            $dt = _elgg_fetch_entities_from_sql($query, $options['__ElggBatch']);
        } else {
            $dt = get_data($query, $options['callback']);
        }
        if ($dt) {
            // populate entity and metadata caches
            $guids = array();
            foreach ($dt as $item) {
                // A custom callback could result in items that aren't ElggEntity's, so check for them
                if ($item instanceof ElggEntity) {
                    _elgg_cache_entity($item);
                    // plugins usually have only settings
                    if (!$item instanceof ElggPlugin) {
                        $guids[] = $item->guid;
                    }
                }
            }
            // @todo Without this, recursive delete fails. See #4568
            reset($dt);
            if ($guids) {
                _elgg_get_metadata_cache()->populateFromEntities($guids);
            }
        }
        return $dt;
    } else {
        $total = get_data_row($query);
        return (int) $total->total;
    }
}
예제 #5
0
 public function testAccessPluginHookAddAnd()
 {
     elgg_register_plugin_hook_handler('get_sql', 'access', array($this, 'addAndCallback'));
     $sql = _elgg_get_access_where_sql();
     $ans = "((1 = 1) AND (e.enabled = 'yes' AND 57 > 32))";
     $this->assertTrue($this->assertSqlEqual($ans, $sql), "{$sql} does not match {$ans}");
 }
/**
 * Returns metadata name and value SQL where for entities.
 * NB: $names and $values are not paired. Use $pairs for this.
 * Pairs default to '=' operand.
 *
 * This function is reused for annotations because the tables are
 * exactly the same.
 *
 * @param string     $e_table           Entities table name
 * @param string     $n_table           Normalized metastrings table name (Where entities,
 *                                    values, and names are joined. annotations / metadata)
 * @param array|null $names             Array of names
 * @param array|null $values            Array of values
 * @param array|null $pairs             Array of names / values / operands
 * @param string     $pair_operator     ("AND" or "OR") Operator to use to join the where clauses for pairs
 * @param bool       $case_sensitive    Case sensitive metadata names?
 * @param array|null $order_by_metadata Array of names / direction
 * @param array|null $owner_guids       Array of owner GUIDs
 *
 * @return false|array False on fail, array('joins', 'wheres')
 * @since 1.7.0
 * @access private
 */
function _elgg_get_entity_metadata_where_sql($e_table, $n_table, $names = null, $values = null, $pairs = null, $pair_operator = 'AND', $case_sensitive = true, $order_by_metadata = null, $owner_guids = null)
{
    global $CONFIG;
    // short circuit if nothing requested
    // 0 is a valid (if not ill-conceived) metadata name.
    // 0 is also a valid metadata value for false, null, or 0
    // 0 is also a valid(ish) owner_guid
    if (!$names && $names !== 0 && (!$values && $values !== 0) && (!$pairs && $pairs !== 0) && (!$owner_guids && $owner_guids !== 0) && !$order_by_metadata) {
        return '';
    }
    // join counter for incremental joins.
    $i = 1;
    // binary forces byte-to-byte comparision of strings, making
    // it case- and diacritical-mark- sensitive.
    // only supported on values.
    $binary = $case_sensitive ? ' BINARY ' : '';
    $access = _elgg_get_access_where_sql(array('table_alias' => 'n_table'));
    $return = array('joins' => array(), 'wheres' => array(), 'orders' => array());
    // will always want to join these tables if pulling metastrings.
    $return['joins'][] = "JOIN {$CONFIG->dbprefix}{$n_table} n_table on\n\t\t{$e_table}.guid = n_table.entity_guid";
    $wheres = array();
    // get names wheres and joins
    $names_where = '';
    if ($names !== null) {
        if (!is_array($names)) {
            $names = array($names);
        }
        $sanitised_names = array();
        foreach ($names as $name) {
            // normalise to 0.
            if (!$name) {
                $name = '0';
            }
            $sanitised_names[] = '\'' . sanitise_string($name) . '\'';
        }
        if ($names_str = implode(',', $sanitised_names)) {
            $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn on n_table.name_id = msn.id";
            $names_where = "(msn.string IN ({$names_str}))";
        }
    }
    // get values wheres and joins
    $values_where = '';
    if ($values !== null) {
        if (!is_array($values)) {
            $values = array($values);
        }
        $sanitised_values = array();
        foreach ($values as $value) {
            // normalize to 0
            if (!$value) {
                $value = 0;
            }
            $sanitised_values[] = '\'' . sanitise_string($value) . '\'';
        }
        if ($values_str = implode(',', $sanitised_values)) {
            $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv on n_table.value_id = msv.id";
            $values_where = "({$binary}msv.string IN ({$values_str}))";
        }
    }
    if ($names_where && $values_where) {
        $wheres[] = "({$names_where} AND {$values_where} AND {$access})";
    } elseif ($names_where) {
        $wheres[] = "({$names_where} AND {$access})";
    } elseif ($values_where) {
        $wheres[] = "({$values_where} AND {$access})";
    }
    // add pairs
    // pairs must be in arrays.
    if (is_array($pairs)) {
        // check if this is an array of pairs or just a single pair.
        if (isset($pairs['name']) || isset($pairs['value'])) {
            $pairs = array($pairs);
        }
        $pair_wheres = array();
        // @todo when the pairs are > 3 should probably split the query up to
        // denormalize the strings table.
        foreach ($pairs as $index => $pair) {
            // @todo move this elsewhere?
            // support shortcut 'n' => 'v' method.
            if (!is_array($pair)) {
                $pair = array('name' => $index, 'value' => $pair);
            }
            // must have at least a name and value
            if (!isset($pair['name']) || !isset($pair['value'])) {
                // @todo should probably return false.
                continue;
            }
            // case sensitivity can be specified per pair.
            // default to higher level setting.
            if (isset($pair['case_sensitive'])) {
                $pair_binary = $pair['case_sensitive'] ? ' BINARY ' : '';
            } else {
                $pair_binary = $binary;
            }
            if (isset($pair['operand'])) {
                $operand = sanitise_string($pair['operand']);
            } else {
                $operand = ' = ';
            }
            // for comparing
            $trimmed_operand = trim(strtolower($operand));
            $access = _elgg_get_access_where_sql(array('table_alias' => "n_table{$i}"));
            // if the value is an int, don't quote it because str '15' < str '5'
            // if the operand is IN don't quote it because quoting should be done already.
            if (is_numeric($pair['value'])) {
                $value = sanitise_string($pair['value']);
            } else {
                if (is_bool($pair['value'])) {
                    $value = (int) $pair['value'];
                } else {
                    if (is_array($pair['value'])) {
                        $values_array = array();
                        foreach ($pair['value'] as $pair_value) {
                            if (is_numeric($pair_value)) {
                                $values_array[] = sanitise_string($pair_value);
                            } else {
                                $values_array[] = "'" . sanitise_string($pair_value) . "'";
                            }
                        }
                        if ($values_array) {
                            $value = '(' . implode(', ', $values_array) . ')';
                        }
                        // @todo allow support for non IN operands with array of values.
                        // will have to do more silly joins.
                        $operand = 'IN';
                    } else {
                        if ($trimmed_operand == 'in') {
                            $value = "({$pair['value']})";
                        } else {
                            $value = "'" . sanitise_string($pair['value']) . "'";
                        }
                    }
                }
            }
            $name = sanitise_string($pair['name']);
            // @todo The multiple joins are only needed when the operator is AND
            $return['joins'][] = "JOIN {$CONFIG->dbprefix}{$n_table} n_table{$i}\n\t\t\t\ton {$e_table}.guid = n_table{$i}.entity_guid";
            $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn{$i}\n\t\t\t\ton n_table{$i}.name_id = msn{$i}.id";
            $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv{$i}\n\t\t\t\ton n_table{$i}.value_id = msv{$i}.id";
            $pair_wheres[] = "(msn{$i}.string = '{$name}' AND {$pair_binary}msv{$i}.string\n\t\t\t\t{$operand} {$value} AND {$access})";
            $i++;
        }
        if ($where = implode(" {$pair_operator} ", $pair_wheres)) {
            $wheres[] = "({$where})";
        }
    }
    // add owner_guids
    if ($owner_guids) {
        if (is_array($owner_guids)) {
            $sanitised = array_map('sanitise_int', $owner_guids);
            $owner_str = implode(',', $sanitised);
        } else {
            $owner_str = sanitise_int($owner_guids);
        }
        $wheres[] = "(n_table.owner_guid IN ({$owner_str}))";
    }
    if ($where = implode(' AND ', $wheres)) {
        $return['wheres'][] = "({$where})";
    }
    if (is_array($order_by_metadata)) {
        if (count($order_by_metadata) > 0 && !isset($order_by_metadata[0])) {
            // singleton, so fix
            $order_by_metadata = array($order_by_metadata);
        }
        foreach ($order_by_metadata as $order_by) {
            if (is_array($order_by) && isset($order_by['name'])) {
                $name = sanitise_string($order_by['name']);
                if (isset($order_by['direction'])) {
                    $direction = sanitise_string($order_by['direction']);
                } else {
                    $direction = 'ASC';
                }
                $return['joins'][] = "JOIN {$CONFIG->dbprefix}{$n_table} n_table{$i}\n\t\t\t\t\ton {$e_table}.guid = n_table{$i}.entity_guid";
                $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msn{$i}\n\t\t\t\t\ton n_table{$i}.name_id = msn{$i}.id";
                $return['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings msv{$i}\n\t\t\t\t\ton n_table{$i}.value_id = msv{$i}.id";
                $access = _elgg_get_access_where_sql(array('table_alias' => "n_table{$i}"));
                $return['wheres'][] = "(msn{$i}.string = '{$name}' AND {$access})";
                if (isset($order_by['as']) && $order_by['as'] == 'integer') {
                    $return['orders'][] = "CAST(msv{$i}.string AS SIGNED) {$direction}";
                } else {
                    $return['orders'][] = "msv{$i}.string {$direction}";
                }
                $i++;
            }
        }
    }
    return $return;
}
예제 #7
0
/**
 * Returns the SQL where clause for a table with access_id and enabled columns.
 *
 * This handles returning where clauses for ACCESS_FRIENDS in addition to using 
 * get_access_list() for access collections and the standard access levels.
 *
 * Note that if this code is executed in privileged mode it will return (1=1).
 *
 * @param string $table_prefix Optional table prefix for the access code.
 * @param int    $owner        Optional user guid to get access information for. Defaults
 *                             to logged in user.
 * @return string
 * @access private
 * @deprecated 1.9 Use _elgg_get_access_where_sql()
 */
function get_access_sql_suffix($table_prefix = '', $owner = null)
{
    elgg_deprecated_notice(__FUNCTION__ . ' is deprecated by _elgg_get_access_where_sql()', 1.9);
    return _elgg_get_access_where_sql(array('table_alias' => $table_prefix, 'user_guid' => (int) $owner));
}
예제 #8
0
파일: EntityTable.php 프로젝트: ibou77/elgg
 /**
  * Returns a list of months in which entities were updated or created.
  *
  * @tip Use this to generate a list of archives by month for when entities were added or updated.
  *
  * @todo document how to pass in array for $subtype
  *
  * @warning Months are returned in the form YYYYMM.
  *
  * @param string $type           The type of entity
  * @param string $subtype        The subtype of entity
  * @param int    $container_guid The container GUID that the entities belong to
  * @param int    $site_guid      The site GUID
  * @param string $order_by       Order_by SQL order by clause
  *
  * @return array|false Either an array months as YYYYMM, or false on failure
  */
 function getDates($type = '', $subtype = '', $container_guid = 0, $site_guid = 0, $order_by = 'time_created')
 {
     $site_guid = (int) $site_guid;
     if ($site_guid == 0) {
         $site_guid = $this->CONFIG->site_guid;
     }
     $where = array();
     if ($type != "") {
         $type = sanitise_string($type);
         $where[] = "type='{$type}'";
     }
     if (is_array($subtype)) {
         $tempwhere = "";
         if (sizeof($subtype)) {
             foreach ($subtype as $typekey => $subtypearray) {
                 foreach ($subtypearray as $subtypeval) {
                     $typekey = sanitise_string($typekey);
                     if (!empty($subtypeval)) {
                         if (!($subtypeval = (int) get_subtype_id($typekey, $subtypeval))) {
                             return false;
                         }
                     } else {
                         $subtypeval = 0;
                     }
                     if (!empty($tempwhere)) {
                         $tempwhere .= " or ";
                     }
                     $tempwhere .= "(type = '{$typekey}' and subtype = {$subtypeval})";
                 }
             }
         }
         if (!empty($tempwhere)) {
             $where[] = "({$tempwhere})";
         }
     } else {
         if ($subtype) {
             if (!($subtype_id = get_subtype_id($type, $subtype))) {
                 return false;
             } else {
                 $where[] = "subtype={$subtype_id}";
             }
         }
     }
     if ($container_guid !== 0) {
         if (is_array($container_guid)) {
             foreach ($container_guid as $key => $val) {
                 $container_guid[$key] = (int) $val;
             }
             $where[] = "container_guid in (" . implode(",", $container_guid) . ")";
         } else {
             $container_guid = (int) $container_guid;
             $where[] = "container_guid = {$container_guid}";
         }
     }
     if ($site_guid > 0) {
         $where[] = "site_guid = {$site_guid}";
     }
     $where[] = _elgg_get_access_where_sql(array('table_alias' => ''));
     $sql = "SELECT DISTINCT EXTRACT(YEAR_MONTH FROM FROM_UNIXTIME(time_created)) AS yearmonth\n\t\t\tFROM {$this->CONFIG->dbprefix}entities where ";
     foreach ($where as $w) {
         $sql .= " {$w} and ";
     }
     $sql .= "1=1 ORDER BY {$order_by}";
     if ($result = _elgg_services()->db->getData($sql)) {
         $endresult = array();
         foreach ($result as $res) {
             $endresult[] = $res->yearmonth;
         }
         return $endresult;
     }
     return false;
 }
예제 #9
0
파일: MetadataCache.php 프로젝트: elgg/elgg
 /**
  * Populate the cache from a set of entities
  *
  * @param int|array $guids Array of or single GUIDs
  * @return void
  */
 public function populateFromEntities($guids)
 {
     if (empty($guids)) {
         return;
     }
     $version = (int) elgg_get_config('version');
     if (!empty($version) && $version < 2016110900) {
         // can't use this during upgrade from 2.x to 3.0
         return;
     }
     $access_key = $this->getAccessKey();
     if (!is_array($guids)) {
         $guids = array($guids);
     }
     $guids = array_unique($guids);
     // could be useful at some point in future
     //$guids = $this->filterMetadataHeavyEntities($guids);
     $db_prefix = _elgg_services()->db->prefix;
     $options = array('guids' => $guids, 'limit' => 0, 'callback' => false, 'distinct' => false, 'order_by' => 'n_table.entity_guid, n_table.time_created ASC, n_table.id ASC', 'wheres' => array(_elgg_get_access_where_sql(array('table_alias' => 'n_table', 'guid_column' => 'entity_guid'))));
     $data = _elgg_services()->metadataTable->getAll($options);
     // make sure we show all entities as loaded
     foreach ($guids as $guid) {
         $this->values[$access_key][$guid] = null;
     }
     // build up metadata for each entity, save when GUID changes (or data ends)
     $last_guid = null;
     $metadata = array();
     $last_row_idx = count($data) - 1;
     foreach ($data as $i => $row) {
         $name = $row->name;
         $value = $row->value_type === 'text' ? $row->value : (int) $row->value;
         $guid = $row->entity_guid;
         if ($guid !== $last_guid) {
             if ($last_guid) {
                 $this->values[$access_key][$last_guid] = $metadata;
             }
             $metadata = array();
         }
         if (isset($metadata[$name])) {
             $metadata[$name] = (array) $metadata[$name];
             $metadata[$name][] = $value;
         } else {
             $metadata[$name] = $value;
         }
         if ($i == $last_row_idx) {
             $this->values[$access_key][$guid] = $metadata;
         }
         $last_guid = $guid;
     }
 }
예제 #10
0
 /**
  * Get an array of users from an email address
  *
  * @param string $email Email address.
  *
  * @return array
  */
 function getByEmail($email)
 {
     $email = sanitise_string($email);
     $access = _elgg_get_access_where_sql();
     $query = "SELECT e.* FROM {$this->CONFIG->dbprefix}entities e\n\t\t\tJOIN {$this->CONFIG->dbprefix}users_entity u ON e.guid = u.guid\n\t\t\tWHERE email = '{$email}' AND {$access}";
     return _elgg_services()->db->getData($query, 'entity_row_to_elggstar');
 }
예제 #11
0
/**
 * Get river items
 *
 * @note If using types and subtypes in a query, they are joined with an AND.
 *
 * @param array $options Parameters:
 *   ids                  => INT|ARR River item id(s)
 *   subject_guids        => INT|ARR Subject guid(s)
 *   object_guids         => INT|ARR Object guid(s)
 *   target_guids         => INT|ARR Target guid(s)
 *   annotation_ids       => INT|ARR The identifier of the annotation(s)
 *   action_types         => STR|ARR The river action type(s) identifier
 *   posted_time_lower    => INT     The lower bound on the time posted
 *   posted_time_upper    => INT     The upper bound on the time posted
 *
 *   types                => STR|ARR Entity type string(s)
 *   subtypes             => STR|ARR Entity subtype string(s)
 *   type_subtype_pairs   => ARR     Array of type => subtype pairs where subtype
 *                                   can be an array of subtype strings
 *
 *   relationship         => STR     Relationship identifier
 *   relationship_guid    => INT|ARR Entity guid(s)
 *   inverse_relationship => BOOL    Subject or object of the relationship (false)
 *
 * 	 limit                => INT     Number to show per page (20)
 *   offset               => INT     Offset in list (0)
 *   count                => BOOL    Count the river items? (false)
 *   order_by             => STR     Order by clause (rv.posted desc)
 *   group_by             => STR     Group by clause
 *
 *   distinct             => BOOL    If set to false, Elgg will drop the DISTINCT
 *                                   clause from the MySQL query, which will improve
 *                                   performance in some situations. Avoid setting this
 *                                   option without a full understanding of the
 *                                   underlying SQL query Elgg creates. (true)
 *
 * @return array|int
 * @since 1.8.0
 */
function elgg_get_group_river(array $options = array())
{
    global $CONFIG;
    //error_log("group river");
    $defaults = array('ids' => ELGG_ENTITIES_ANY_VALUE, 'subject_guids' => ELGG_ENTITIES_ANY_VALUE, 'object_guids' => ELGG_ENTITIES_ANY_VALUE, 'target_guids' => ELGG_ENTITIES_ANY_VALUE, 'annotation_ids' => ELGG_ENTITIES_ANY_VALUE, 'action_types' => ELGG_ENTITIES_ANY_VALUE, 'relationship' => null, 'relationship_guid' => null, 'inverse_relationship' => false, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'limit' => 20, 'offset' => 0, 'count' => false, 'distinct' => false, 'order_by' => 'u.posted desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'wheres' => array(), 'wheres1' => array(), 'wheres2' => array(), 'joins' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('id', 'subject_guid', 'object_guid', 'target_guid', 'annotation_id', 'action_type', 'type', 'subtype');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $wheres1 = $options['wheres1'];
    $wheres2 = $options['wheres2'];
    /*
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.id', $options['ids']);
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.subject_guid', $options['subject_guids']);
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.object_guid', $options['object_guids']);
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.target_guid', $options['target_guids']);
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.annotation_id', $options['annotation_ids']);
    	$wheres[] = _elgg_river_get_action_where_sql($options['action_types']);
    	$wheres[] = _elgg_get_river_type_subtype_where_sql('rv', $options['types'],
    		$options['subtypes'], $options['type_subtype_pairs']);
    */
    /*if ($options['posted_time_lower'] && is_int($options['posted_time_lower'])) {
    		$wheres1[] = "rv.posted >= {$options['posted_time_lower']}";
    		$wheres2[] = "rv.posted >= {$options['posted_time_lower']}";
    	}
    
    	if ($options['posted_time_upper'] && is_int($options['posted_time_upper'])) {
    		$wheres1[] = "rv.posted <= {$options['posted_time_upper']}";
    		$wheres2[] = "rv.posted <= {$options['posted_time_upper']}";
    	}*/
    if (!access_get_show_hidden_status()) {
        $wheres1[] = "rv.enabled = 'yes'";
        $wheres2[] = "rv.enabled = 'yes'";
    }
    $dbprefix = elgg_get_config('dbprefix');
    $join1 = "JOIN {$dbprefix}entities oe ON rv.object_guid = oe.guid";
    // LEFT JOIN is used because all river items do not necessarily have target
    $join2 = "LEFT JOIN {$dbprefix}entities te ON rv.target_guid = te.guid";
    // see if any functions failed
    // remove empty strings on successful functions
    /*foreach ($wheres1 as $i => $where) {
    		if ($where === false) {
    			return false;
    		} elseif (empty($where)) {
    			unset($wheres1[$i]);
    		}
    	}
    	foreach ($wheres2 as $i => $where) {
    		if ($where === false) {
    			return false;
    		} elseif (empty($where)) {
    			unset($wheres2[$i]);
    		}
    	}
    
    	// remove identical where clauses
    	$wheres1 = array_unique($wheres1);
    	$wheres2 = array_unique($wheres2);
    	*/
    // Wheres for the 2 parts of the union query
    $w1 = "";
    foreach ($wheres1 as $w) {
        $w1 .= " {$w} AND ";
    }
    $w2 = "";
    foreach ($wheres2 as $w) {
        $w2 .= " {$w} AND ";
    }
    // Make sure that user has access to all the entities referenced by each river item
    $object_access_where = _elgg_get_access_where_sql(array('table_alias' => 'oe'));
    $target_access_where = _elgg_get_access_where_sql(array('table_alias' => 'te'));
    if (!$options['count']) {
        $GOL = "";
        // Group by / order / limit
        $options['group_by'] = sanitise_string($options['group_by']);
        if ($options['group_by']) {
            $GOL .= " GROUP BY {$options['group_by']}";
        }
        $options['order_by'] = sanitise_string($options['order_by']);
        $GOL .= " ORDER BY {$options['order_by']}";
        if ($options['limit']) {
            $limit = sanitise_int($options['limit']);
            $offset = sanitise_int($options['offset'], false);
            $GOL .= " LIMIT {$offset}, {$limit}";
        }
        // custom UNION - based query
        $query = "SELECT u.* FROM ( ( SELECT rv.* FROM {$CONFIG->dbprefix}river rv {$join1} WHERE {$w1} {$object_access_where} ) UNION " . "( SELECT rv.* FROM {$CONFIG->dbprefix}river rv {$join2} WHERE {$w2} ({$target_access_where} OR te.guid IS NULL) ) ) u {$GOL}";
        $river_items = get_data($query, '_elgg_row_to_elgg_river_item');
        _elgg_prefetch_river_entities($river_items);
        //	error_log($query);
        return $river_items;
    } else {
        $query = "SELECT sum(count) as total FROM ( ( SELECT count(*) as count FROM {$CONFIG->dbprefix}river rv {$join1} WHERE {$w1} {$object_access_where} ) UNION " . "( SELECT count(*) as count FROM {$CONFIG->dbprefix}river rv {$join2} WHERE {$w2} ({$target_access_where} OR te.guid IS NULL) ) ) u";
        //	error_log($query);
        $total = get_data_row($query);
        return (int) $total->total;
    }
}
예제 #12
0
/**
 * Can a user access an entity.
 *
 * @warning If a logged in user doesn't have access to an entity, the
 * core engine will not load that entity.
 *
 * @tip This is mostly useful for checking if a user other than the logged in
 * user has access to an entity that is currently loaded.
 *
 * @todo This function would be much more useful if we could pass the guid of the
 * entity to test access for. We need to be able to tell whether the entity exists
 * and whether the user has access to the entity.
 *
 * @param ElggEntity $entity The entity to check access for.
 * @param ElggUser   $user   Optionally user to check access for. Defaults to
 *                           logged in user (which is a useless default).
 *
 * @return bool
 */
function has_access_to_entity($entity, $user = null)
{
    global $CONFIG;
    // See #7159. Must not allow ignore access to affect query
    $ia = elgg_set_ignore_access(false);
    if (!isset($user)) {
        $access_bit = _elgg_get_access_where_sql();
    } else {
        $access_bit = _elgg_get_access_where_sql(array('user_guid' => $user->getGUID()));
    }
    elgg_set_ignore_access($ia);
    $query = "SELECT guid from {$CONFIG->dbprefix}entities e WHERE e.guid = " . $entity->getGUID();
    // Add access controls
    $query .= " AND " . $access_bit;
    if (get_data($query)) {
        return true;
    } else {
        return false;
    }
}
예제 #13
0
$offset = 0;
$limit = (int) $widget->num_display;
if ($limit < 1) {
    $limit = 10;
}
$sql = "SELECT {$dbprefix}river.*";
$sql .= " FROM {$dbprefix}river";
$sql .= " INNER JOIN {$dbprefix}entities AS entities1 ON {$dbprefix}river.object_guid = entities1.guid";
$sql .= ' WHERE (entities1.container_guid in (' . implode(',', $group_guid) . ')';
$sql .= " OR {$dbprefix}river.object_guid IN (" . implode(',', $group_guid) . '))';
if (!empty($activity_filter) && is_string($activity_filter)) {
    list($type, $subtype) = explode(',', $activity_filter);
    if (!empty($type)) {
        $filter_where = " ({$dbprefix}river.type = '" . sanitise_string($type) . "'";
        if (!empty($subtype)) {
            $filter_where .= " AND {$dbprefix}river.subtype = '" . sanitise_string($subtype) . "'";
        }
        $filter_where .= ')';
        $sql .= ' AND ' . $filter_where;
    }
}
$sql .= ' AND ' . _elgg_get_access_where_sql(['table_alias' => 'entities1']);
$sql .= " ORDER BY {$dbprefix}river.posted DESC";
$sql .= " LIMIT {$offset},{$limit}";
$items = get_data($sql, '_elgg_row_to_elgg_river_item');
if (empty($items)) {
    echo elgg_echo('widgets:group_river_widget:view:noactivity');
    return;
}
$options = ['pagination' => false, 'count' => count($items), 'items' => $items, 'list_class' => 'elgg-list-river elgg-river', 'limit' => $limit, 'offset' => $offset];
echo elgg_view('page/components/list', $options);
예제 #14
0
파일: access.php 프로젝트: tjcaverly/Elgg
/**
 * Can a user access an entity.
 *
 * @warning If a logged in user doesn't have access to an entity, the
 * core engine will not load that entity.
 *
 * @tip This is mostly useful for checking if a user other than the logged in
 * user has access to an entity that is currently loaded.
 *
 * @todo This function would be much more useful if we could pass the guid of the
 * entity to test access for. We need to be able to tell whether the entity exists
 * and whether the user has access to the entity.
 *
 * @param ElggEntity $entity The entity to check access for.
 * @param ElggUser   $user   Optionally user to check access for. Defaults to
 *                           logged in user (which is a useless default).
 *
 * @return bool
 */
function has_access_to_entity($entity, $user = null)
{
    global $CONFIG;
    if (!isset($user)) {
        $access_bit = _elgg_get_access_where_sql();
    } else {
        $access_bit = _elgg_get_access_where_sql(array('user_guid' => $user->getGUID()));
    }
    $query = "SELECT guid from {$CONFIG->dbprefix}entities e WHERE e.guid = " . $entity->getGUID();
    // Add access controls
    $query .= " AND " . $access_bit;
    if (get_data($query)) {
        return true;
    } else {
        return false;
    }
}
예제 #15
0
파일: MetadataTable.php 프로젝트: elgg/elgg
 /**
  * Returns metadata name and value SQL where for entities.
  * NB: $names and $values are not paired. Use $pairs for this.
  * Pairs default to '=' operand.
  *
  * This function is reused for annotations because the tables are
  * exactly the same.
  *
  * @param string     $e_table           Entities table name
  * @param string     $n_table           Normalized metastrings table name (Where entities,
  *                                    values, and names are joined. annotations / metadata)
  * @param array|null $names             Array of names
  * @param array|null $values            Array of values
  * @param array|null $pairs             Array of names / values / operands
  * @param string     $pair_operator     ("AND" or "OR") Operator to use to join the where clauses for pairs
  * @param bool       $case_sensitive    Case sensitive metadata names?
  * @param array|null $order_by_metadata Array of names / direction
  * @param array|null $owner_guids       Array of owner GUIDs
  *
  * @return false|array False on fail, array('joins', 'wheres')
  * @access private
  */
 function getEntityMetadataWhereSql($e_table, $n_table, $names = null, $values = null, $pairs = null, $pair_operator = 'AND', $case_sensitive = true, $order_by_metadata = null, $owner_guids = null)
 {
     // short circuit if nothing requested
     // 0 is a valid (if not ill-conceived) metadata name.
     // 0 is also a valid metadata value for false, null, or 0
     // 0 is also a valid(ish) owner_guid
     if (!$names && $names !== 0 && (!$values && $values !== 0) && (!$pairs && $pairs !== 0) && (!$owner_guids && $owner_guids !== 0) && !$order_by_metadata) {
         return '';
     }
     // join counter for incremental joins.
     $i = 1;
     // binary forces byte-to-byte comparision of strings, making
     // it case- and diacritical-mark- sensitive.
     // only supported on values.
     $binary = $case_sensitive ? ' BINARY ' : '';
     $access = _elgg_get_access_where_sql(array('table_alias' => 'n_table', 'guid_column' => 'entity_guid'));
     $return = array('joins' => array(), 'wheres' => array(), 'orders' => array());
     $return['joins'][] = "JOIN {$this->db->prefix}{$n_table} n_table on\n\t\t\t{$e_table}.guid = n_table.entity_guid";
     $wheres = array();
     // get names wheres and joins
     $names_where = '';
     if ($names !== null) {
         if (!is_array($names)) {
             $names = array($names);
         }
         $sanitised_names = array();
         foreach ($names as $name) {
             // normalise to 0.
             if (!$name) {
                 $name = '0';
             }
             $sanitised_names[] = '\'' . $this->db->sanitizeString($name) . '\'';
         }
         if ($names_str = implode(',', $sanitised_names)) {
             $names_where = "(n_table.name IN ({$names_str}))";
         }
     }
     // get values wheres and joins
     $values_where = '';
     if ($values !== null) {
         if (!is_array($values)) {
             $values = array($values);
         }
         $sanitised_values = array();
         foreach ($values as $value) {
             // normalize to 0
             if (!$value) {
                 $value = 0;
             }
             $sanitised_values[] = '\'' . $this->db->sanitizeString($value) . '\'';
         }
         if ($values_str = implode(',', $sanitised_values)) {
             $values_where = "({$binary}n_table.value IN ({$values_str}))";
         }
     }
     if ($names_where && $values_where) {
         $wheres[] = "({$names_where} AND {$values_where} AND {$access})";
     } elseif ($names_where) {
         $wheres[] = "({$names_where} AND {$access})";
     } elseif ($values_where) {
         $wheres[] = "({$values_where} AND {$access})";
     }
     // add pairs
     // pairs must be in arrays.
     if (is_array($pairs)) {
         // check if this is an array of pairs or just a single pair.
         if (isset($pairs['name']) || isset($pairs['value'])) {
             $pairs = array($pairs);
         }
         $pair_wheres = array();
         // @todo when the pairs are > 3 should probably split the query up to
         // denormalize the strings table.
         foreach ($pairs as $index => $pair) {
             // @todo move this elsewhere?
             // support shortcut 'n' => 'v' method.
             if (!is_array($pair)) {
                 $pair = array('name' => $index, 'value' => $pair);
             }
             // must have at least a name and value
             if (!isset($pair['name']) || !isset($pair['value'])) {
                 // @todo should probably return false.
                 continue;
             }
             // case sensitivity can be specified per pair.
             // default to higher level setting.
             if (isset($pair['case_sensitive'])) {
                 $pair_binary = $pair['case_sensitive'] ? ' BINARY ' : '';
             } else {
                 $pair_binary = $binary;
             }
             if (isset($pair['operand'])) {
                 $operand = $this->db->sanitizeString($pair['operand']);
             } else {
                 $operand = ' = ';
             }
             // for comparing
             $trimmed_operand = trim(strtolower($operand));
             $access = _elgg_get_access_where_sql(array('table_alias' => "n_table{$i}", 'guid_column' => 'entity_guid'));
             // certain operands can't work well with strings that can be interpreted as numbers
             // for direct comparisons like IN, =, != we treat them as strings
             // gt/lt comparisons need to stay unencapsulated because strings '5' > '15'
             // see https://github.com/Elgg/Elgg/issues/7009
             $num_safe_operands = array('>', '<', '>=', '<=');
             $num_test_operand = trim(strtoupper($operand));
             if (is_numeric($pair['value']) && in_array($num_test_operand, $num_safe_operands)) {
                 $value = $this->db->sanitizeString($pair['value']);
             } else {
                 if (is_bool($pair['value'])) {
                     $value = (int) $pair['value'];
                 } else {
                     if (is_array($pair['value'])) {
                         $values_array = array();
                         foreach ($pair['value'] as $pair_value) {
                             if (is_numeric($pair_value) && !in_array($num_test_operand, $num_safe_operands)) {
                                 $values_array[] = $this->db->sanitizeString($pair_value);
                             } else {
                                 $values_array[] = "'" . $this->db->sanitizeString($pair_value) . "'";
                             }
                         }
                         if ($values_array) {
                             $value = '(' . implode(', ', $values_array) . ')';
                         }
                         // @todo allow support for non IN operands with array of values.
                         // will have to do more silly joins.
                         $operand = 'IN';
                     } else {
                         if ($trimmed_operand == 'in') {
                             $value = "({$pair['value']})";
                         } else {
                             $value = "'" . $this->db->sanitizeString($pair['value']) . "'";
                         }
                     }
                 }
             }
             $name = $this->db->sanitizeString($pair['name']);
             $return['joins'][] = "JOIN {$this->db->prefix}{$n_table} n_table{$i}\n\t\t\t\t\ton {$e_table}.guid = n_table{$i}.entity_guid";
             $pair_wheres[] = "(n_table{$i}.name = '{$name}' AND {$pair_binary}n_table{$i}.value\n\t\t\t\t\t{$operand} {$value} AND {$access})";
             $i++;
         }
         if ($where = implode(" {$pair_operator} ", $pair_wheres)) {
             $wheres[] = "({$where})";
         }
     }
     // add owner_guids
     if ($owner_guids) {
         if (is_array($owner_guids)) {
             $sanitised = array_map('sanitise_int', $owner_guids);
             $owner_str = implode(',', $sanitised);
         } else {
             $owner_str = (int) $owner_guids;
         }
         $wheres[] = "(n_table.owner_guid IN ({$owner_str}))";
     }
     if ($where = implode(' AND ', $wheres)) {
         $return['wheres'][] = "({$where})";
     }
     if (is_array($order_by_metadata)) {
         if (count($order_by_metadata) > 0 && !isset($order_by_metadata[0])) {
             // singleton, so fix
             $order_by_metadata = array($order_by_metadata);
         }
         foreach ($order_by_metadata as $order_by) {
             if (is_array($order_by) && isset($order_by['name'])) {
                 $name = $this->db->sanitizeString($order_by['name']);
                 if (isset($order_by['direction'])) {
                     $direction = $this->db->sanitizeString($order_by['direction']);
                 } else {
                     $direction = 'ASC';
                 }
                 $return['joins'][] = "JOIN {$this->db->prefix}{$n_table} n_table{$i}\n\t\t\t\t\t\ton {$e_table}.guid = n_table{$i}.entity_guid";
                 $access = _elgg_get_access_where_sql(array('table_alias' => "n_table{$i}", 'guid_column' => 'entity_guid'));
                 $return['wheres'][] = "(n_table{$i}.name = '{$name}' AND {$access})";
                 if (isset($order_by['as']) && $order_by['as'] == 'integer') {
                     $return['orders'][] = "CAST(n_table{$i}.value AS SIGNED) {$direction}";
                 } else {
                     $return['orders'][] = "n_table{$i}.value {$direction}";
                 }
                 $i++;
             }
         }
     }
     return $return;
 }
예제 #16
0
파일: MetadataTable.php 프로젝트: elgg/elgg
 /**
  * Add query query_specs for a metadata object
  *
  * @param stdClass $row Data row
  * @return void
  */
 public function addQuerySpecs(stdClass $row)
 {
     $this->clearQuerySpecs($row);
     // Return this metadata object when _elgg_get_metastring_based_objects() is called
     $e_access_sql = _elgg_get_access_where_sql(array('table_alias' => 'e'));
     $md_access_sql = _elgg_get_access_where_sql(array('table_alias' => 'n_table', 'guid_column' => 'entity_guid'));
     $dbprefix = elgg_get_config('dbprefix');
     $sql = "SELECT DISTINCT  n_table.*\n\t\t\tFROM {$dbprefix}metadata n_table\n\t\t\t\tJOIN {$dbprefix}entities e ON n_table.entity_guid = e.guid\n\t\t\t\tWHERE  (n_table.id IN ({$row->id}) AND {$md_access_sql}) AND {$e_access_sql}\n\t\t\t\tORDER BY n_table.time_created ASC, n_table.id ASC, n_table.id";
     $this->query_specs[$row->id][] = $this->db->addQuerySpec(['sql' => $sql, 'results' => function () use($row) {
         if (isset($this->rows[$row->id])) {
             return [$this->rows[$row->id]];
         }
         return [];
     }]);
     $sql = "INSERT INTO {$dbprefix}metadata\n\t\t\t\t(entity_guid, name, value, value_type, owner_guid, time_created, access_id)\n\t\t\t\tVALUES (:entity_guid, :name, :value, :value_type, :owner_guid, :time_created, :access_id)";
     $this->query_specs[$row->id][] = $this->db->addQuerySpec(['sql' => $sql, 'params' => [':entity_guid' => $row->entity_guid, ':name' => $row->name, ':value' => $row->value, ':value_type' => $row->value_type, ':owner_guid' => $row->owner_guid, ':time_created' => $row->time_created, ':access_id' => $row->access_id], 'insert_id' => $row->id]);
     $sql = "UPDATE {$dbprefix}metadata\n\t\t\tSET name = :name,\n\t\t\t    value = :value,\n\t\t\t\tvalue_type = :value_type,\n\t\t\t\taccess_id = :access_id,\n\t\t\t    owner_guid = :owner_guid\n\t\t\tWHERE id = :id";
     $this->query_specs[$row->id][] = $this->db->addQuerySpec(['sql' => $sql, 'params' => [':name' => $row->name, ':value' => $row->value, ':value_type' => $row->value_type, ':owner_guid' => $row->owner_guid, ':access_id' => $row->access_id, ':id' => $row->id], 'results' => function () use($row) {
         if (isset($this->rows[$row->id])) {
             return [$row->id];
         }
         return [];
     }]);
     // Enable/disable metadata
     $sql = "UPDATE {$dbprefix}metadata SET enabled = :enabled where id = :id";
     $this->query_specs[$row->id][] = $this->db->addQuerySpec(['sql' => $sql, 'params' => [':id' => $row->id, ':enabled' => 'yes'], 'results' => function () use($row) {
         if (isset($this->rows[$row->id])) {
             $this->rows[$row->id]->enabled = 'yes';
             return [$row->id];
         }
         return [];
     }]);
     $this->query_specs[$row->id][] = $this->db->addQuerySpec(['sql' => $sql, 'params' => [':id' => $row->id, ':enabled' => 'no'], 'results' => function () use($row) {
         if (isset($this->rows[$row->id])) {
             $this->rows[$row->id]->enabled = 'no';
             return [$row->id];
         }
         return [];
     }]);
     // Delete
     $sql = "DELETE FROM {$dbprefix}metadata WHERE id = :id";
     $this->query_specs[$row->id][] = $this->db->addQuerySpec(['sql' => $sql, 'params' => [':id' => $row->id], 'results' => function () use($row) {
         if (isset($this->rows[$row->id])) {
             unset($this->rows[$row->id]);
             $this->clearQuerySpecs($row);
             return [$row->id];
         }
         return [];
     }]);
 }
예제 #17
0
 /**
  * Populate the cache from a set of entities
  * 
  * @param int|array $guids Array of or single GUIDs
  * @return void
  */
 public function populateFromEntities($guids)
 {
     if (empty($guids)) {
         return;
     }
     if (!is_array($guids)) {
         $guids = array($guids);
     }
     $guids = array_unique($guids);
     // could be useful at some point in future
     //$guids = $this->filterMetadataHeavyEntities($guids);
     $db_prefix = elgg_get_config('dbprefix');
     $options = array('guids' => $guids, 'limit' => 0, 'callback' => false, 'joins' => array("JOIN {$db_prefix}metastrings v ON n_table.value_id = v.id", "JOIN {$db_prefix}metastrings n ON n_table.name_id = n.id"), 'selects' => array('n.string AS name', 'v.string AS value'), 'order_by' => 'n_table.entity_guid, n_table.time_created ASC', 'wheres' => array(_elgg_get_access_where_sql(array('table_alias' => 'n_table'))));
     $data = elgg_get_metadata($options);
     // build up metadata for each entity, save when GUID changes (or data ends)
     $last_guid = null;
     $metadata = array();
     $last_row_idx = count($data) - 1;
     foreach ($data as $i => $row) {
         $name = $row->name;
         $value = $row->value_type === 'text' ? $row->value : (int) $row->value;
         $guid = $row->entity_guid;
         if ($guid !== $last_guid) {
             if ($last_guid) {
                 $this->saveAll($last_guid, $metadata);
             }
             $metadata = array();
         }
         if (isset($metadata[$name])) {
             $metadata[$name] = (array) $metadata[$name];
             $metadata[$name][] = $value;
         } else {
             $metadata[$name] = $value;
         }
         if ($i == $last_row_idx) {
             $this->saveAll($guid, $metadata);
         }
         $last_guid = $guid;
     }
 }
예제 #18
0
 /**
  * Get Elgg access SQL suffix
  *
  * @param string $table_alias Table alias
  * @return string
  */
 function sqlGetAccessSuffix($table_alias = 'e')
 {
     return _elgg_get_access_where_sql(array('table_alias' => $table_alias));
 }
예제 #19
0
/**
 * Construct and execute the query required for the activity stream.
 *
 * @deprecated 1.8 This is outdated and uses the systemlog table instead of the river table.
 *                 Don't use it.
 */
function get_activity_stream_data($limit = 10, $offset = 0, $type = "", $subtype = "", $owner_guid = "", $owner_relationship = "")
{
    elgg_deprecated_notice("get_activity_stream_data was deprecated", 1.8);
    global $CONFIG;
    $limit = (int) $limit;
    $offset = (int) $offset;
    if ($type) {
        if (!is_array($type)) {
            $type = array(sanitise_string($type));
        } else {
            foreach ($type as $k => $v) {
                $type[$k] = sanitise_string($v);
            }
        }
    }
    if ($subtype) {
        if (!is_array($subtype)) {
            $subtype = array(sanitise_string($subtype));
        } else {
            foreach ($subtype as $k => $v) {
                $subtype[$k] = sanitise_string($v);
            }
        }
    }
    if ($owner_guid) {
        if (is_array($owner_guid)) {
            foreach ($owner_guid as $k => $v) {
                $owner_guid[$k] = (int) $v;
            }
        } else {
            $owner_guid = array((int) $owner_guid);
        }
    }
    $owner_relationship = sanitise_string($owner_relationship);
    // Get a list of possible views
    $activity_events = array();
    $activity_views = array_merge(elgg_view_tree('activity', 'default'), elgg_view_tree('river', 'default'));
    $done = array();
    foreach ($activity_views as $view) {
        $fragments = explode('/', $view);
        $tmp = explode('/', $view, 2);
        $tmp = $tmp[1];
        if (isset($fragments[0]) && ($fragments[0] == 'river' || $fragments[0] == 'activity') && !in_array($tmp, $done)) {
            if (isset($fragments[1])) {
                $f = array();
                for ($n = 1; $n < count($fragments); $n++) {
                    $val = sanitise_string($fragments[$n]);
                    switch ($n) {
                        case 1:
                            $key = 'type';
                            break;
                        case 2:
                            $key = 'subtype';
                            break;
                        case 3:
                            $key = 'event';
                            break;
                    }
                    $f[$key] = $val;
                }
                // Filter result based on parameters
                $add = true;
                if ($type) {
                    if (!in_array($f['type'], $type)) {
                        $add = false;
                    }
                }
                if ($add && $subtype) {
                    if (!in_array($f['subtype'], $subtype)) {
                        $add = false;
                    }
                }
                if ($add && $event) {
                    if (!in_array($f['event'], $event)) {
                        $add = false;
                    }
                }
                if ($add) {
                    $activity_events[] = $f;
                }
            }
            $done[] = $tmp;
        }
    }
    $n = 0;
    foreach ($activity_events as $details) {
        // Get what we're talking about
        if ($details['subtype'] == 'default') {
            $details['subtype'] = '';
        }
        if ($details['type'] && $details['event']) {
            if ($n > 0) {
                $obj_query .= " or ";
            }
            $access = "";
            if ($details['type'] != 'relationship') {
                $access = " and " . _elgg_get_access_where_sql(array('table_alias' => 'sl'));
            }
            $obj_query .= "( sl.object_type='{$details['type']}'\n\t\t\t\tAND sl.object_subtype='{$details['subtype']}'\n\t\t\t\tAND sl.event='{$details['event']}' {$access} )";
            $n++;
        }
    }
    // User
    if (count($owner_guid) && $owner_guid[0] != 0) {
        $user = "******" . implode(',', $owner_guid) . ")";
        if ($owner_relationship) {
            $friendsarray = "";
            if ($friends = elgg_get_entities_from_relationship(array('relationship' => $owner_relationship, 'relationship_guid' => $owner_guid[0], 'inverse_relationship' => FALSE, 'type' => 'user', 'subtype' => $subtype, 'limit' => false))) {
                $friendsarray = array();
                foreach ($friends as $friend) {
                    $friendsarray[] = $friend->getGUID();
                }
                $user = "******" . implode(',', $friendsarray) . ")";
            }
        }
    }
    $query = "SELECT sl.* FROM {$CONFIG->dbprefix}system_log sl\n\t\tWHERE 1 {$user} AND ({$obj_query})\n\t\tORDER BY sl.time_created desc limit {$offset}, {$limit}";
    return get_data($query);
}
예제 #20
0
function elgg_solr_get_annotation_ids($options)
{
    $options = _elgg_normalize_metastrings_options($options);
    $type = 'annotations';
    $callback = false;
    $defaults = array('types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'guids' => ELGG_ENTITIES_ANY_VALUE, 'owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'container_guids' => ELGG_ENTITIES_ANY_VALUE, 'site_guids' => get_config('site_guid'), 'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'metastring_names' => ELGG_ENTITIES_ANY_VALUE, 'metastring_values' => ELGG_ENTITIES_ANY_VALUE, 'metastring_case_sensitive' => true, 'metastring_calculation' => ELGG_ENTITIES_NO_VALUE, 'metastring_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'metastring_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'metastring_owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'metastring_ids' => ELGG_ENTITIES_ANY_VALUE, 'order_by' => 'n_table.time_created ASC, n_table.id ASC', 'limit' => elgg_get_config('default_limit'), 'offset' => 0, 'count' => false, 'selects' => array(), 'wheres' => array(), 'joins' => array(), 'distinct' => true, 'preload_owners' => false, 'callback' => $callback);
    // @todo Ignore site_guid right now because of #2910
    $options['site_guid'] = ELGG_ENTITIES_ANY_VALUE;
    $options = array_merge($defaults, $options);
    // can't use helper function with type_subtype_pair because
    // it's already an array...just need to merge it
    if (isset($options['type_subtype_pair'])) {
        if (isset($options['type_subtype_pairs'])) {
            $options['type_subtype_pairs'] = array_merge($options['type_subtype_pairs'], $options['type_subtype_pair']);
        } else {
            $options['type_subtype_pairs'] = $options['type_subtype_pair'];
        }
    }
    $singulars = array('type', 'subtype', 'type_subtype_pair', 'guid', 'owner_guid', 'container_guid', 'site_guid', 'metastring_name', 'metastring_value', 'metastring_owner_guid', 'metastring_id', 'select', 'where', 'join');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    if (!$options) {
        return false;
    }
    $db_prefix = elgg_get_config('dbprefix');
    // evaluate where clauses
    if (!is_array($options['wheres'])) {
        $options['wheres'] = array($options['wheres']);
    }
    $wheres = $options['wheres'];
    // entities
    $wheres[] = _elgg_services()->entityTable->getEntityTypeSubtypeWhereSql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.guid', $options['guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']);
    $wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']);
    $wheres[] = _elgg_get_entity_time_where_sql('n_table', $options['metastring_created_time_upper'], $options['metastring_created_time_lower'], null, null);
    $wheres[] = _elgg_get_guid_based_where_sql('n_table.owner_guid', $options['metastring_owner_guids']);
    // see if any functions failed
    // remove empty strings on successful functions
    foreach ($wheres as $i => $where) {
        if ($where === false) {
            return false;
        } elseif (empty($where)) {
            unset($wheres[$i]);
        }
    }
    // remove identical where clauses
    $wheres = array_unique($wheres);
    // evaluate join clauses
    if (!is_array($options['joins'])) {
        $options['joins'] = array($options['joins']);
    }
    $joins = $options['joins'];
    $joins[] = "JOIN {$db_prefix}entities e ON n_table.entity_guid = e.guid";
    // evaluate selects
    if (!is_array($options['selects'])) {
        $options['selects'] = array($options['selects']);
    }
    $selects = $options['selects'];
    // For performance reasons we don't want the joins required for metadata / annotations
    // unless we're going through one of their callbacks.
    // this means we expect the functions passing different callbacks to pass their required joins.
    // If we're doing a calculation
    $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";
        $selects[] = 'n.string as name';
        $selects[] = 'v.string as value';
    }
    foreach ($joins as $i => $join) {
        if ($join === false) {
            return false;
        } elseif (empty($join)) {
            unset($joins[$i]);
        }
    }
    // metastrings
    $metastring_clauses = _elgg_get_metastring_sql('n_table', $options['metastring_names'], $options['metastring_values'], null, $options['metastring_ids'], $options['metastring_case_sensitive']);
    if ($metastring_clauses) {
        $wheres = array_merge($wheres, $metastring_clauses['wheres']);
        $joins = array_merge($joins, $metastring_clauses['joins']);
    } else {
        $wheres[] = _elgg_get_access_where_sql(array('table_alias' => 'n_table', 'guid_column' => 'entity_guid'));
    }
    $distinct = $options['distinct'] ? "DISTINCT " : "";
    if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) {
        $selects = array_unique($selects);
        // evalutate selects
        $select_str = '';
        if ($selects) {
            foreach ($selects as $select) {
                $select_str .= ", {$select}";
            }
        }
        $query = "SELECT {$distinct} n_table.id{$select_str} FROM {$db_prefix}{$type} n_table";
    } elseif ($options['count']) {
        // count is over the entities
        $query = "SELECT count({$distinct} e.guid) as calculation FROM {$db_prefix}{$type} n_table";
    } else {
        $query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}{$type} n_table";
    }
    // remove identical join clauses
    $joins = array_unique($joins);
    // add joins
    foreach ($joins as $j) {
        $query .= " {$j} ";
    }
    // add wheres
    $query .= ' WHERE ';
    foreach ($wheres as $w) {
        $query .= " {$w} AND ";
    }
    // Add access controls
    $query .= _elgg_get_access_where_sql(array('table_alias' => 'e'));
    // reverse order by
    if (isset($options['reverse_order_by']) && $options['reverse_order_by']) {
        $options['order_by'] = _elgg_sql_reverse_order_by_clause($options['order_by']);
    }
    if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) {
        if (isset($options['group_by'])) {
            $options['group_by'] = sanitise_string($options['group_by']);
            $query .= " GROUP BY {$options['group_by']}";
        }
        if (isset($options['order_by']) && $options['order_by']) {
            $options['order_by'] = sanitise_string($options['order_by']);
            $query .= " ORDER BY {$options['order_by']}, n_table.id";
        }
        if ($options['limit']) {
            $limit = sanitise_int($options['limit']);
            $offset = sanitise_int($options['offset'], false);
            $query .= " LIMIT {$offset}, {$limit}";
        }
        $dt = get_data($query, $options['callback']);
        return $dt;
    } else {
        $result = get_data_row($query);
        return $result->calculation;
    }
}
/**
 * Searches for a user based on a complete or partial name or username.
 *
 * @param string  $criteria The partial or full name or username.
 * @param int     $limit    Limit of the search.
 * @param int     $offset   Offset.
 * @param string  $order_by The order.
 * @param boolean $count    Whether to return the count of results or just the results.
 *
 * @return mixed
 * @deprecated 1.7
 */
function search_for_user($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false)
{
    elgg_deprecated_notice('search_for_user() was deprecated by new search.', 1.7);
    global $CONFIG;
    $criteria = sanitise_string($criteria);
    $limit = (int) $limit;
    $offset = (int) $offset;
    $order_by = sanitise_string($order_by);
    $access = _elgg_get_access_where_sql();
    if ($order_by == "") {
        $order_by = "e.time_created desc";
    }
    if ($count) {
        $query = "SELECT count(e.guid) as total ";
    } else {
        $query = "SELECT e.* ";
    }
    $query .= "from {$CONFIG->dbprefix}entities e\n\t\tjoin {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where ";
    $query .= "(u.name like \"%{$criteria}%\" or u.username like \"%{$criteria}%\")";
    $query .= " and {$access}";
    if (!$count) {
        $query .= " order by {$order_by} limit {$offset}, {$limit}";
        return get_data($query, "entity_row_to_elggstar");
    } else {
        if ($count = get_data_row($query)) {
            return $count->total;
        }
    }
    return false;
}
예제 #22
0
/**
 * Returns an array of joins and wheres for use in metastrings.
 *
 * @note The $pairs is reserved for name/value pairs if we want to implement those.
 *
 * @param string $table          The annotation or metadata table name or alias
 * @param array  $names          An array of names
 * @param array  $values         An array of values
 * @param array  $pairs          Name / value pairs. Not currently used.
 * @param array  $ids            Metastring IDs
 * @param bool   $case_sensitive Should name and values be case sensitive?
 *
 * @return array
 * @access private
 */
function _elgg_get_metastring_sql($table, $names = null, $values = null, $pairs = null, $ids = null, $case_sensitive = false)
{
    if (!$names && $names !== 0 && (!$values && $values !== 0) && !$ids && (!$pairs && $pairs !== 0)) {
        return array();
    }
    $db_prefix = elgg_get_config('dbprefix');
    // binary forces byte-to-byte comparision of strings, making
    // it case- and diacritical-mark- sensitive.
    // only supported on values.
    $binary = $case_sensitive ? ' BINARY ' : '';
    $return = array('joins' => array(), 'wheres' => array());
    $wheres = array();
    // get names wheres and joins
    $names_where = '';
    if ($names !== null) {
        if (!is_array($names)) {
            $names = array($names);
        }
        $sanitised_names = array();
        foreach ($names as $name) {
            // normalise to 0.
            if (!$name) {
                $name = '0';
            }
            $sanitised_names[] = '\'' . sanitise_string($name) . '\'';
        }
        if ($names_str = implode(',', $sanitised_names)) {
            $return['joins'][] = "JOIN {$db_prefix}metastrings msn on {$table}.name_id = msn.id";
            $names_where = "(msn.string IN ({$names_str}))";
        }
    }
    // get values wheres and joins
    $values_where = '';
    if ($values !== null) {
        if (!is_array($values)) {
            $values = array($values);
        }
        $sanitised_values = array();
        foreach ($values as $value) {
            // normalize to 0
            if (!$value) {
                $value = 0;
            }
            $sanitised_values[] = '\'' . sanitise_string($value) . '\'';
        }
        if ($values_str = implode(',', $sanitised_values)) {
            $return['joins'][] = "JOIN {$db_prefix}metastrings msv on {$table}.value_id = msv.id";
            $values_where = "({$binary}msv.string IN ({$values_str}))";
        }
    }
    if ($ids !== null) {
        if (!is_array($ids)) {
            $ids = array($ids);
        }
        $ids_str = implode(',', $ids);
        if ($ids_str) {
            $wheres[] = "n_table.id IN ({$ids_str})";
        }
    }
    if ($names_where && $values_where) {
        $wheres[] = "({$names_where} AND {$values_where})";
    } elseif ($names_where) {
        $wheres[] = $names_where;
    } elseif ($values_where) {
        $wheres[] = $values_where;
    }
    $wheres[] = _elgg_get_access_where_sql(array('table_alias' => $table));
    if ($where = implode(' AND ', $wheres)) {
        $return['wheres'][] = "({$where})";
    }
    return $return;
}
예제 #23
0
파일: river.php 프로젝트: ibou77/elgg
/**
 * Get river items
 *
 * @note If using types and subtypes in a query, they are joined with an AND.
 *
 * @param array $options Parameters:
 *   ids                  => INT|ARR River item id(s)
 *   subject_guids        => INT|ARR Subject guid(s)
 *   object_guids         => INT|ARR Object guid(s)
 *   target_guids         => INT|ARR Target guid(s)
 *   annotation_ids       => INT|ARR The identifier of the annotation(s)
 *   action_types         => STR|ARR The river action type(s) identifier
 *   posted_time_lower    => INT     The lower bound on the time posted
 *   posted_time_upper    => INT     The upper bound on the time posted
 *
 *   types                => STR|ARR Entity type string(s)
 *   subtypes             => STR|ARR Entity subtype string(s)
 *   type_subtype_pairs   => ARR     Array of type => subtype pairs where subtype
 *                                   can be an array of subtype strings
 *
 *   relationship         => STR     Relationship identifier
 *   relationship_guid    => INT|ARR Entity guid(s)
 *   inverse_relationship => BOOL    Subject or object of the relationship (false)
 *
 * 	 limit                => INT     Number to show per page (20)
 *   offset               => INT     Offset in list (0)
 *   count                => BOOL    Count the river items? (false)
 *   order_by             => STR     Order by clause (rv.posted desc)
 *   group_by             => STR     Group by clause
 *
 *   distinct             => BOOL    If set to false, Elgg will drop the DISTINCT
 *                                   clause from the MySQL query, which will improve
 *                                   performance in some situations. Avoid setting this
 *                                   option without a full understanding of the
 *                                   underlying SQL query Elgg creates. (true)
 *
 * @return array|int
 * @since 1.8.0
 */
function elgg_get_river(array $options = array())
{
    global $CONFIG;
    $defaults = array('ids' => ELGG_ENTITIES_ANY_VALUE, 'subject_guids' => ELGG_ENTITIES_ANY_VALUE, 'object_guids' => ELGG_ENTITIES_ANY_VALUE, 'target_guids' => ELGG_ENTITIES_ANY_VALUE, 'annotation_ids' => ELGG_ENTITIES_ANY_VALUE, 'action_types' => ELGG_ENTITIES_ANY_VALUE, 'relationship' => null, 'relationship_guid' => null, 'inverse_relationship' => false, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'limit' => 20, 'offset' => 0, 'count' => false, 'distinct' => true, 'order_by' => 'rv.posted desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'wheres' => array(), 'joins' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('id', 'subject_guid', 'object_guid', 'target_guid', 'annotation_id', 'action_type', 'type', 'subtype');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $wheres = $options['wheres'];
    $wheres[] = _elgg_get_guid_based_where_sql('rv.id', $options['ids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.subject_guid', $options['subject_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.object_guid', $options['object_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.target_guid', $options['target_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.annotation_id', $options['annotation_ids']);
    $wheres[] = _elgg_river_get_action_where_sql($options['action_types']);
    $wheres[] = _elgg_get_river_type_subtype_where_sql('rv', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
    if ($options['posted_time_lower'] && is_int($options['posted_time_lower'])) {
        $wheres[] = "rv.posted >= {$options['posted_time_lower']}";
    }
    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[] = "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";
    if ($options['relationship_guid']) {
        $clauses = elgg_get_entity_relationship_where_sql('rv.subject_guid', $options['relationship'], $options['relationship_guid'], $options['inverse_relationship']);
        if ($clauses) {
            $wheres = array_merge($wheres, $clauses['wheres']);
            $joins = array_merge($joins, $clauses['joins']);
        }
    }
    // see if any functions failed
    // remove empty strings on successful functions
    foreach ($wheres as $i => $where) {
        if ($where === false) {
            return false;
        } elseif (empty($where)) {
            unset($wheres[$i]);
        }
    }
    // remove identical where clauses
    $wheres = array_unique($wheres);
    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 ";
    }
    // add joins
    foreach ($joins as $j) {
        $query .= " {$j} ";
    }
    // add wheres
    $query .= ' WHERE ';
    foreach ($wheres as $w) {
        $query .= " {$w} AND ";
    }
    // Make sure that user has access to all the entities referenced by each river item
    $object_access_where = _elgg_get_access_where_sql(array('table_alias' => 'oe'));
    $target_access_where = _elgg_get_access_where_sql(array('table_alias' => 'te'));
    // We use LEFT JOIN with entities table but the WHERE clauses are used
    // regardless if a JOIN is successfully made. The "te.guid IS NULL" is
    // needed because of this.
    $query .= "{$object_access_where} AND ({$target_access_where} OR te.guid IS NULL) ";
    if (!$options['count']) {
        $options['group_by'] = sanitise_string($options['group_by']);
        if ($options['group_by']) {
            $query .= " GROUP BY {$options['group_by']}";
        }
        $options['order_by'] = sanitise_string($options['order_by']);
        $query .= " ORDER BY {$options['order_by']}";
        if ($options['limit']) {
            $limit = sanitise_int($options['limit']);
            $offset = sanitise_int($options['offset'], false);
            $query .= " LIMIT {$offset}, {$limit}";
        }
        $river_items = get_data($query, '_elgg_row_to_elgg_river_item');
        _elgg_prefetch_river_entities($river_items);
        return $river_items;
    } else {
        $total = get_data_row($query);
        return (int) $total->total;
    }
}
예제 #24
0
파일: river.php 프로젝트: tjcaverly/Elgg
/**
 * Get the river's access where clause
 *
 * @return string
 * @since 1.8.0
 * @access private
 */
function elgg_river_get_access_sql()
{
    // @todo deprecate? this is only used once in elgg_get_river
    return _elgg_get_access_where_sql(array('table_alias' => '', 'owner_guid_column' => 'rv.subject_guid', 'guid_column' => 'object_guid', 'access_id_column' => 'rv.access_id', 'use_enabled_clause' => false));
}
예제 #25
0
/**
 * Get popular tags and their frequencies
 *
 * Supports similar arguments as elgg_get_entities()
 *
 * @param array $options Array in format:
 *
 * 	threshold => INT minimum tag count
 *
 * 	tag_names => array() metadata tag names - must be registered tags
 *
 * 	limit => INT number of tags to return
 *
 *  types => null|STR entity type (SQL: type = '$type')
 *
 * 	subtypes => null|STR entity subtype (SQL: subtype = '$subtype')
 *
 * 	type_subtype_pairs => null|ARR (array('type' => 'subtype'))
 *  (SQL: type = '$type' AND subtype = '$subtype') pairs
 *
 * 	owner_guids => null|INT entity guid
 *
 * 	container_guids => null|INT container_guid
 *
 * 	site_guids => null (current_site)|INT site_guid
 *
 * 	created_time_lower => null|INT Created time lower boundary in epoch time
 *
 * 	created_time_upper => null|INT Created time upper boundary in epoch time
 *
 * 	modified_time_lower => null|INT Modified time lower boundary in epoch time
 *
 * 	modified_time_upper => null|INT Modified time upper boundary in epoch time
 *
 * 	wheres => array() Additional where clauses to AND together
 *
 * 	joins => array() Additional joins
 *
 * @return 	object[]|false If no tags or error, false
 * 						   otherwise, array of objects with ->tag and ->total values
 * @since 1.7.1
 */
function elgg_get_tags(array $options = array())
{
    global $CONFIG;
    $defaults = array('threshold' => 1, 'tag_names' => array(), 'limit' => 10, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'container_guids' => ELGG_ENTITIES_ANY_VALUE, 'site_guids' => $CONFIG->site_guid, 'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'joins' => array(), 'wheres' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('type', 'subtype', 'owner_guid', 'container_guid', 'site_guid', 'tag_name');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $registered_tags = elgg_get_registered_tag_metadata_names();
    if (!is_array($options['tag_names'])) {
        return false;
    }
    // empty array so use all registered tag names
    if (count($options['tag_names']) == 0) {
        $options['tag_names'] = $registered_tags;
    }
    $diff = array_diff($options['tag_names'], $registered_tags);
    if (count($diff) > 0) {
        elgg_deprecated_notice('Tag metadata names must be registered by elgg_register_tag_metadata_name()', 1.7);
        // return false;
    }
    $wheres = $options['wheres'];
    // catch for tags that were spaces
    $wheres[] = "msv.string != ''";
    $sanitised_tags = array();
    foreach ($options['tag_names'] as $tag) {
        $sanitised_tags[] = '"' . sanitise_string($tag) . '"';
    }
    $tags_in = implode(',', $sanitised_tags);
    $wheres[] = "(msn.string IN ({$tags_in}))";
    $wheres[] = _elgg_get_entity_type_subtype_where_sql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']);
    $wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']);
    // see if any functions failed
    // remove empty strings on successful functions
    foreach ($wheres as $i => $where) {
        if ($where === false) {
            return false;
        } elseif (empty($where)) {
            unset($wheres[$i]);
        }
    }
    // remove identical where clauses
    $wheres = array_unique($wheres);
    $joins = $options['joins'];
    $joins[] = "JOIN {$CONFIG->dbprefix}metadata md on md.entity_guid = e.guid";
    $joins[] = "JOIN {$CONFIG->dbprefix}metastrings msv on msv.id = md.value_id";
    $joins[] = "JOIN {$CONFIG->dbprefix}metastrings msn on md.name_id = msn.id";
    // remove identical join clauses
    $joins = array_unique($joins);
    foreach ($joins as $i => $join) {
        if ($join === false) {
            return false;
        } elseif (empty($join)) {
            unset($joins[$i]);
        }
    }
    $query = "SELECT msv.string as tag, count(msv.id) as total ";
    $query .= "FROM {$CONFIG->dbprefix}entities e ";
    // add joins
    foreach ($joins as $j) {
        $query .= " {$j} ";
    }
    // add wheres
    $query .= ' WHERE ';
    foreach ($wheres as $w) {
        $query .= " {$w} AND ";
    }
    // Add access controls
    $query .= _elgg_get_access_where_sql();
    $threshold = sanitise_int($options['threshold']);
    $query .= " GROUP BY msv.string HAVING total >= {$threshold} ";
    $query .= " ORDER BY total DESC ";
    $limit = sanitise_int($options['limit']);
    $query .= " LIMIT {$limit} ";
    return get_data($query);
}
예제 #26
0
파일: river.php 프로젝트: coldtrick/digest
*
*/
$user = elgg_extract("user", $vars, elgg_get_logged_in_user_entity());
$group = elgg_extract("group", $vars);
$ts_lower = (int) elgg_extract("ts_lower", $vars);
$ts_upper = (int) elgg_extract("ts_upper", $vars);
$dbprefix = get_config("dbprefix");
$group_guid = $group->getGUID();
$offset = 0;
$limit = 25;
// retrieve recent group activity
$sql = "SELECT r.*";
$sql .= " FROM " . $dbprefix . "river r";
$sql .= " INNER JOIN " . $dbprefix . "entities AS e ON r.object_guid = e.guid";
// river event -> object
$sql .= " WHERE (e.container_guid = {$group_guid} OR r.object_guid = {$group_guid})";
// filter by group
$sql .= " AND r.posted BETWEEN " . $ts_lower . " AND " . $ts_upper;
// filter interval
$sql .= " AND " . _elgg_get_access_where_sql(array("table_alias" => "e"));
// filter access
$sql .= " ORDER BY posted DESC";
$sql .= " LIMIT " . $offset . "," . $limit;
$items = get_data($sql, "_elgg_row_to_elgg_river_item");
if (!empty($items)) {
    $title = elgg_view("output/url", array("text" => elgg_echo("groups:activity"), "href" => $group->getURL(), "is_trusted" => true));
    $options = array("list_class" => "elgg-list-river elgg-river", "items" => $items, "pagination" => false);
    $content = elgg_view("page/components/list", $options);
    echo elgg_view_module("digest", $title, $content);
}
unset($items);
예제 #27
0
/**
 * Get entities with tags that match the search parameters.
 *
 * @param string $hook   Hook name
 * @param string $type   Hook type
 * @param array  $value  Empty array
 * @param array  $params Search parameters
 * @return array
 */
function search_tags_hook($hook, $type, $value, $params)
{
    $params['joins'] = (array) elgg_extract('joins', $params, array());
    $params['wheres'] = (array) elgg_extract('wheres', $params, array());
    $db_prefix = elgg_get_config('dbprefix');
    $valid_tag_names = elgg_get_registered_tag_metadata_names();
    // @todo will need to split this up to support searching multiple tags at once.
    $query = sanitise_string($params['query']);
    // if passed a tag metadata name, only search on that tag name.
    // tag_name isn't included in the params because it's specific to
    // tag searches.
    if ($tag_names = get_input('tag_names')) {
        if (is_array($tag_names)) {
            $search_tag_names = $tag_names;
        } else {
            $search_tag_names = array($tag_names);
        }
        // check these are valid to avoid arbitrary metadata searches.
        foreach ($search_tag_names as $i => $tag_name) {
            if (!in_array($tag_name, $valid_tag_names)) {
                unset($search_tag_names[$i]);
            }
        }
    } else {
        $search_tag_names = $valid_tag_names;
    }
    if (!$search_tag_names) {
        return array('entities' => array(), 'count' => $count);
    }
    // don't use elgg_get_entities_from_metadata() here because of
    // performance issues.  since we don't care what matches at this point
    // use an IN clause to grab everything that matches at once and sort
    // out the matches later.
    $params['joins'][] = "JOIN {$db_prefix}metadata md on e.guid = md.entity_guid";
    $params['joins'][] = "JOIN {$db_prefix}metastrings msn on md.name_id = msn.id";
    $params['joins'][] = "JOIN {$db_prefix}metastrings msv on md.value_id = msv.id";
    $access = _elgg_get_access_where_sql(array('table_alias' => 'md'));
    $sanitised_tags = array();
    foreach ($search_tag_names as $tag) {
        $sanitised_tags[] = '"' . sanitise_string($tag) . '"';
    }
    $tags_in = implode(',', $sanitised_tags);
    $params['wheres'][] = "(msn.string IN ({$tags_in}) AND msv.string = '{$query}' AND {$access})";
    $params['count'] = TRUE;
    $count = elgg_get_entities($params);
    // no need to continue if nothing here.
    if (!$count) {
        return array('entities' => array(), 'count' => $count);
    }
    $params['count'] = FALSE;
    if (isset($params['sort']) || !isset($params['order_by'])) {
        $params['order_by'] = search_get_order_by_sql('e', null, $params['sort'], $params['order']);
    }
    $entities = elgg_get_entities($params);
    // add the volatile data for why these entities have been returned.
    foreach ($entities as $entity) {
        $matched_tags_strs = array();
        // get tags for each tag name requested to find which ones matched.
        foreach ($search_tag_names as $tag_name) {
            $tags = $entity->getTags($tag_name);
            // @todo make one long tag string and run this through the highlight
            // function.  This might be confusing as it could chop off
            // the tag labels.
            if (in_array(strtolower($query), array_map('strtolower', $tags))) {
                if (is_array($tags)) {
                    $tag_name_str = elgg_echo("tag_names:{$tag_name}");
                    $matched_tags_strs[] = "{$tag_name_str}: " . implode(', ', $tags);
                }
            }
        }
        // different entities have different titles
        switch ($entity->type) {
            case 'site':
            case 'user':
            case 'group':
                $title_tmp = $entity->name;
                break;
            case 'object':
                $title_tmp = $entity->title;
                break;
        }
        // Nick told me my idea was dirty, so I'm hard coding the numbers.
        $title_tmp = strip_tags($title_tmp);
        if (elgg_strlen($title_tmp) > 297) {
            $title_str = elgg_substr($title_tmp, 0, 297) . '...';
        } else {
            $title_str = $title_tmp;
        }
        $desc_tmp = strip_tags($entity->description);
        if (elgg_strlen($desc_tmp) > 297) {
            $desc_str = elgg_substr($desc_tmp, 0, 297) . '...';
        } else {
            $desc_str = $desc_tmp;
        }
        $tags_str = implode('. ', $matched_tags_strs);
        $tags_str = search_get_highlighted_relevant_substrings($tags_str, $params['query'], 30, 300, true);
        $entity->setVolatileData('search_matched_title', $title_str);
        $entity->setVolatileData('search_matched_description', $desc_str);
        $entity->setVolatileData('search_matched_extra', $tags_str);
    }
    return array('entities' => $entities, 'count' => $count);
}
예제 #28
0
 /**
  * Can a user access an entity.
  *
  * @warning If a logged in user doesn't have access to an entity, the
  * core engine will not load that entity.
  *
  * @tip This is mostly useful for checking if a user other than the logged in
  * user has access to an entity that is currently loaded.
  *
  * @todo This function would be much more useful if we could pass the guid of the
  * entity to test access for. We need to be able to tell whether the entity exists
  * and whether the user has access to the entity.
  *
  * @param \ElggEntity $entity The entity to check access for.
  * @param \ElggUser   $user   Optionally user to check access for. Defaults to
  *                           logged in user (which is a useless default).
  *
  * @return bool
  */
 function hasAccessToEntity($entity, $user = null)
 {
     // See #7159. Must not allow ignore access to affect query
     $ia = elgg_set_ignore_access(false);
     if (!isset($user)) {
         $access_bit = _elgg_get_access_where_sql();
     } else {
         $access_bit = _elgg_get_access_where_sql(array('user_guid' => $user->getGUID()));
     }
     elgg_set_ignore_access($ia);
     $db = _elgg_services()->db;
     $prefix = $db->getTablePrefix();
     $query = "SELECT guid from {$prefix}entities e WHERE e.guid = {$entity->guid}";
     // Add access controls
     $query .= " AND " . $access_bit;
     if ($db->getData($query)) {
         return true;
     } else {
         return false;
     }
 }
예제 #29
0
파일: content.php 프로젝트: n8b/VMN
    $values_where .= ")";
}
// excluded tags
$excluded_values = string_to_tag_array($widget->excluded_tags);
if ($excluded_values) {
    // and value_id not in
    $value_ids = array();
    foreach ($excluded_values as $excluded_value) {
        $value_ids += elgg_get_metastring_id($excluded_value, false);
    }
    if (!empty($values_where)) {
        $values_where .= " AND ";
    }
    $values_where .= "e.guid NOT IN (SELECT DISTINCT entity_guid FROM " . $dbprefix . "metadata WHERE name_id IN (" . implode(",", $name_ids) . ") AND value_id IN (" . implode(",", $value_ids) . "))";
}
$access = _elgg_get_access_where_sql(array("table_alias" => 'n_table'));
if ($names_where && $values_where) {
    $wheres[] = "({$names_where} AND {$values_where} AND {$access})";
} elseif ($names_where) {
    $wheres[] = "({$names_where} AND {$access})";
} elseif ($values_where) {
    $wheres[] = "({$values_where} AND {$access})";
}
$options = array("type" => "object", "subtypes" => $content_type, "limit" => $count, "full_view" => false, "pagination" => false, "joins" => $joins, "wheres" => $wheres);
// owner_guids
if (!empty($widget->owner_guids)) {
    if (!is_array($widget->owner_guids)) {
        $owner_guids = string_to_tag_array($widget->owner_guids);
    } else {
        $owner_guids = $widget->owner_guids;
    }
예제 #30
0
 /**
  * Populate the cache from a set of entities
  *
  * @param int|array $guids Array of or single GUIDs
  * @return void
  */
 public function populateFromEntities($guids)
 {
     if (empty($guids)) {
         return;
     }
     $access_key = $this->getAccessKey();
     if (!is_array($guids)) {
         $guids = array($guids);
     }
     $guids = array_unique($guids);
     // could be useful at some point in future
     //$guids = $this->filterMetadataHeavyEntities($guids);
     $db_prefix = _elgg_services()->db->getTablePrefix();
     $options = array('guids' => $guids, 'limit' => 0, 'callback' => false, 'distinct' => false, 'joins' => array("JOIN {$db_prefix}metastrings v ON n_table.value_id = v.id", "JOIN {$db_prefix}metastrings n ON n_table.name_id = n.id"), 'selects' => array('n.string AS name', 'v.string AS value'), 'order_by' => 'n_table.entity_guid, n_table.time_created ASC, n_table.id ASC', 'wheres' => array(_elgg_get_access_where_sql(array('table_alias' => 'n_table', 'guid_column' => 'entity_guid'))));
     $data = _elgg_services()->metadataTable->getAll($options);
     // make sure we show all entities as loaded
     foreach ($guids as $guid) {
         $this->values[$access_key][$guid] = null;
     }
     // build up metadata for each entity, save when GUID changes (or data ends)
     $last_guid = null;
     $metadata = array();
     $last_row_idx = count($data) - 1;
     foreach ($data as $i => $row) {
         $name = $row->name;
         $value = $row->value_type === 'text' ? $row->value : (int) $row->value;
         $guid = $row->entity_guid;
         if ($guid !== $last_guid) {
             if ($last_guid) {
                 $this->values[$access_key][$last_guid] = $metadata;
             }
             $metadata = array();
         }
         if (isset($metadata[$name])) {
             $metadata[$name] = (array) $metadata[$name];
             $metadata[$name][] = $value;
         } else {
             $metadata[$name] = $value;
         }
         if ($i == $last_row_idx) {
             $this->values[$access_key][$guid] = $metadata;
         }
         $last_guid = $guid;
     }
 }