diff options
Diffstat (limited to 'engine/lib/private_settings.php')
-rw-r--r-- | engine/lib/private_settings.php | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/engine/lib/private_settings.php b/engine/lib/private_settings.php new file mode 100644 index 000000000..7541f7b3b --- /dev/null +++ b/engine/lib/private_settings.php @@ -0,0 +1,414 @@ +<?php +/** + * Private settings for entities + * Private settings provide metadata like storage of settings for plugins + * and users. + * + * @package Elgg.Core + * @subpackage PrivateSettings + */ + +/** + * Returns entities based upon private settings. Also accepts all + * options available to elgg_get_entities(). Supports + * the singular option shortcut. + * + * @see elgg_get_entities + * + * @param array $options Array in format: + * + * private_setting_names => NULL|ARR private setting names + * + * private_setting_values => NULL|ARR metadata values + * + * private_setting_name_value_pairs => NULL|ARR ( + * name => 'name', + * value => 'value', + * 'operand' => '=', + * ) + * Currently if multiple values are sent via + * an array (value => array('value1', 'value2') + * the pair's operand will be forced to "IN". + * + * private_setting_name_value_pairs_operator => NULL|STR The operator to use for combining + * (name = value) OPERATOR (name = value); default AND + * + * private_setting_name_prefix => STR A prefix to apply to all private settings. Used to + * namespace plugin user settings or by plugins to namespace + * their own settings. + * + * + * @return mixed int If count, int. If not count, array. false on errors. + * @since 1.8.0 + */ +function elgg_get_entities_from_private_settings(array $options = array()) { + $defaults = array( + 'private_setting_names' => ELGG_ENTITIES_ANY_VALUE, + 'private_setting_values' => ELGG_ENTITIES_ANY_VALUE, + 'private_setting_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, + 'private_setting_name_value_pairs_operator' => 'AND', + 'private_setting_name_prefix' => '', + ); + + $options = array_merge($defaults, $options); + + $singulars = array('private_setting_name', 'private_setting_value', + 'private_setting_name_value_pair'); + + $options = elgg_normalise_plural_options_array($options, $singulars); + + $clauses = elgg_get_entity_private_settings_where_sql('e', $options['private_setting_names'], + $options['private_setting_values'], $options['private_setting_name_value_pairs'], + $options['private_setting_name_value_pairs_operator'], $options['private_setting_name_prefix']); + + if ($clauses) { + // merge wheres to pass to get_entities() + if (isset($options['wheres']) && !is_array($options['wheres'])) { + $options['wheres'] = array($options['wheres']); + } elseif (!isset($options['wheres'])) { + $options['wheres'] = array(); + } + + $options['wheres'] = array_merge($options['wheres'], $clauses['wheres']); + + // merge joins to pass to get_entities() + if (isset($options['joins']) && !is_array($options['joins'])) { + $options['joins'] = array($options['joins']); + } elseif (!isset($options['joins'])) { + $options['joins'] = array(); + } + + $options['joins'] = array_merge($options['joins'], $clauses['joins']); + } + + return elgg_get_entities($options); +} + +/** + * Returns private setting name and value SQL where/join clauses for entities. + * + * @param string $table Entities table name + * @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 Operator for joining pairs where clauses + * @param string $name_prefix A string to prefix all names with + * @return array + * @since 1.8.0 + * @access private + */ +function elgg_get_entity_private_settings_where_sql($table, $names = NULL, $values = NULL, +$pairs = NULL, $pair_operator = 'AND', $name_prefix = '') { + + global $CONFIG; + + // @todo short circuit test + + $return = array ( + 'joins' => array (), + 'wheres' => array(), + ); + + $return['joins'][] = "JOIN {$CONFIG->dbprefix}private_settings ps on + {$table}.guid = ps.entity_guid"; + + $wheres = array(); + + // get names wheres + $names_where = ''; + if ($names !== NULL) { + if (!is_array($names)) { + $names = array($names); + } + + $sanitised_names = array(); + foreach ($names as $name) { + $name = $name_prefix . $name; + $sanitised_names[] = '\'' . sanitise_string($name) . '\''; + } + + $names_str = implode(',', $sanitised_names); + if ($names_str) { + $names_where = "(ps.name IN ($names_str))"; + } + } + + // get values wheres + $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) . '\''; + } + + $values_str = implode(',', $sanitised_values); + if ($values_str) { + $values_where = "(ps.value IN ($values_str))"; + } + } + + if ($names_where && $values_where) { + $wheres[] = "($names_where AND $values_where)"; + } elseif ($names_where) { + $wheres[] = "($names_where)"; + } elseif ($values_where) { + $wheres[] = "($values_where)"; + } + + // add pairs which must be in arrays. + if (is_array($pairs)) { + // join counter for incremental joins in pairs + $i = 1; + + // 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(); + + 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; + } + + if (isset($pair['operand'])) { + $operand = sanitise_string($pair['operand']); + } else { + $operand = ' = '; + } + + // for comparing + $trimmed_operand = trim(strtolower($operand)); + + // 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_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($name_prefix . $pair['name']); + + // @todo The multiple joins are only needed when the operator is AND + $return['joins'][] = "JOIN {$CONFIG->dbprefix}private_settings ps{$i} + on {$table}.guid = ps{$i}.entity_guid"; + + $pair_wheres[] = "(ps{$i}.name = '$name' AND ps{$i}.value + $operand $value)"; + + $i++; + } + + $where = implode(" $pair_operator ", $pair_wheres); + if ($where) { + $wheres[] = "($where)"; + } + } + + $where = implode(' AND ', $wheres); + if ($where) { + $return['wheres'][] = "($where)"; + } + + return $return; +} + +/** + * Gets a private setting for an entity. + * + * Plugin authors can set private data on entities. By default + * private data will not be searched or exported. + * + * @internal Private data is used to store settings for plugins + * and user settings. + * + * @param int $entity_guid The entity GUID + * @param string $name The name of the setting + * + * @return mixed The setting value, or false on failure + * @see set_private_setting() + * @see get_all_private_settings() + * @see remove_private_setting() + * @see remove_all_private_settings() + * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings + */ +function get_private_setting($entity_guid, $name) { + global $CONFIG; + $entity_guid = (int) $entity_guid; + $name = sanitise_string($name); + + $entity = get_entity($entity_guid); + if (!$entity instanceof ElggEntity) { + return false; + } + + $query = "SELECT value from {$CONFIG->dbprefix}private_settings + where name = '{$name}' and entity_guid = {$entity_guid}"; + $setting = get_data_row($query); + + if ($setting) { + return $setting->value; + } + return false; +} + +/** + * Return an array of all private settings. + * + * @param int $entity_guid The entity GUID + * + * @return array|false + * @see set_private_setting() + * @see get_private_settings() + * @see remove_private_setting() + * @see remove_all_private_settings() + * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings + */ +function get_all_private_settings($entity_guid) { + global $CONFIG; + + $entity_guid = (int) $entity_guid; + $entity = get_entity($entity_guid); + if (!$entity instanceof ElggEntity) { + return false; + } + + $query = "SELECT * from {$CONFIG->dbprefix}private_settings where entity_guid = {$entity_guid}"; + $result = get_data($query); + if ($result) { + $return = array(); + foreach ($result as $r) { + $return[$r->name] = $r->value; + } + + return $return; + } + + return false; +} + +/** + * Sets a private setting for an entity. + * + * @param int $entity_guid The entity GUID + * @param string $name The name of the setting + * @param string $value The value of the setting + * + * @return bool + * @see get_private_setting() + * @see get_all_private_settings() + * @see remove_private_setting() + * @see remove_all_private_settings() + * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings + */ +function set_private_setting($entity_guid, $name, $value) { + global $CONFIG; + + $entity_guid = (int) $entity_guid; + $name = sanitise_string($name); + $value = sanitise_string($value); + + $result = insert_data("INSERT into {$CONFIG->dbprefix}private_settings + (entity_guid, name, value) VALUES + ($entity_guid, '$name', '$value') + ON DUPLICATE KEY UPDATE value='$value'"); + + return $result !== false; +} + +/** + * Deletes a private setting for an entity. + * + * @param int $entity_guid The Entity GUID + * @param string $name The name of the setting + * + * @return bool + * @see get_private_setting() + * @see get_all_private_settings() + * @see set_private_setting() + * @see remove_all_private_settings() + * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings + */ +function remove_private_setting($entity_guid, $name) { + global $CONFIG; + + $entity_guid = (int) $entity_guid; + + $entity = get_entity($entity_guid); + if (!$entity instanceof ElggEntity) { + return false; + } + + $name = sanitise_string($name); + + return delete_data("DELETE from {$CONFIG->dbprefix}private_settings + WHERE name = '{$name}' + AND entity_guid = {$entity_guid}"); +} + +/** + * Deletes all private settings for an entity. + * + * @param int $entity_guid The Entity GUID + * + * @return bool + * @see get_private_setting() + * @see get_all_private_settings() + * @see set_private_setting() + * @see remove_private_settings() + * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings + */ +function remove_all_private_settings($entity_guid) { + global $CONFIG; + + $entity_guid = (int) $entity_guid; + + $entity = get_entity($entity_guid); + if (!$entity instanceof ElggEntity) { + return false; + } + + return delete_data("DELETE from {$CONFIG->dbprefix}private_settings + WHERE entity_guid = {$entity_guid}"); +} |