aboutsummaryrefslogtreecommitdiff
path: root/engine/lib/input.php
diff options
context:
space:
mode:
Diffstat (limited to 'engine/lib/input.php')
-rw-r--r--engine/lib/input.php520
1 files changed, 520 insertions, 0 deletions
diff --git a/engine/lib/input.php b/engine/lib/input.php
new file mode 100644
index 000000000..80b0b8766
--- /dev/null
+++ b/engine/lib/input.php
@@ -0,0 +1,520 @@
+<?php
+/**
+ * Parameter input functions.
+ * This file contains functions for getting input from get/post variables.
+ *
+ * @package Elgg.Core
+ * @subpackage Input
+ */
+
+/**
+ * Get some input from variables passed submitted through GET or POST.
+ *
+ * If using any data obtained from get_input() in a web page, please be aware that
+ * it is a possible vector for a reflected XSS attack. If you are expecting an
+ * integer, cast it to an int. If it is a string, escape quotes.
+ *
+ * Note: this function does not handle nested arrays (ex: form input of param[m][n])
+ * because of the filtering done in htmlawed from the filter_tags call.
+ * @todo Is this ^ still true?
+ *
+ * @param string $variable The variable name we want.
+ * @param mixed $default A default value for the variable if it is not found.
+ * @param bool $filter_result If true, then the result is filtered for bad tags.
+ *
+ * @return mixed
+ */
+function get_input($variable, $default = NULL, $filter_result = TRUE) {
+
+ global $CONFIG;
+
+ $result = $default;
+
+ elgg_push_context('input');
+
+ if (isset($CONFIG->input[$variable])) {
+ $result = $CONFIG->input[$variable];
+
+ if ($filter_result) {
+ $result = filter_tags($result);
+ }
+ } elseif (isset($_REQUEST[$variable])) {
+ if (is_array($_REQUEST[$variable])) {
+ $result = $_REQUEST[$variable];
+ } else {
+ $result = trim($_REQUEST[$variable]);
+ }
+
+ if ($filter_result) {
+ $result = filter_tags($result);
+ }
+ }
+
+ elgg_pop_context();
+
+ return $result;
+}
+
+/**
+ * Sets an input value that may later be retrieved by get_input
+ *
+ * Note: this function does not handle nested arrays (ex: form input of param[m][n])
+ *
+ * @param string $variable The name of the variable
+ * @param string|string[] $value The value of the variable
+ *
+ * @return void
+ */
+function set_input($variable, $value) {
+ global $CONFIG;
+ if (!isset($CONFIG->input)) {
+ $CONFIG->input = array();
+ }
+
+ if (is_array($value)) {
+ array_walk_recursive($value, create_function('&$v, $k', '$v = trim($v);'));
+ $CONFIG->input[trim($variable)] = $value;
+ } else {
+ $CONFIG->input[trim($variable)] = trim($value);
+ }
+}
+
+/**
+ * Filter tags from a given string based on registered hooks.
+ *
+ * @param mixed $var Anything that does not include an object (strings, ints, arrays)
+ * This includes multi-dimensional arrays.
+ *
+ * @return mixed The filtered result - everything will be strings
+ */
+function filter_tags($var) {
+ return elgg_trigger_plugin_hook('validate', 'input', null, $var);
+}
+
+/**
+ * Validates an email address.
+ *
+ * @param string $address Email address.
+ *
+ * @return bool
+ */
+function is_email_address($address) {
+ return filter_var($address, FILTER_VALIDATE_EMAIL) === $address;
+}
+
+/**
+ * Load all the REQUEST variables into the sticky form cache
+ *
+ * Call this from an action when you want all your submitted variables
+ * available if the submission fails validation and is sent back to the form
+ *
+ * @param string $form_name Name of the sticky form
+ *
+ * @return void
+ * @link http://docs.elgg.org/Tutorials/UI/StickyForms
+ * @since 1.8.0
+ */
+function elgg_make_sticky_form($form_name) {
+
+ elgg_clear_sticky_form($form_name);
+
+ if (!isset($_SESSION['sticky_forms'])) {
+ $_SESSION['sticky_forms'] = array();
+ }
+ $_SESSION['sticky_forms'][$form_name] = array();
+
+ foreach ($_REQUEST as $key => $var) {
+ // will go through XSS filtering on the get function
+ $_SESSION['sticky_forms'][$form_name][$key] = $var;
+ }
+}
+
+/**
+ * Clear the sticky form cache
+ *
+ * Call this if validation is successful in the action handler or
+ * when they sticky values have been used to repopulate the form
+ * after a validation error.
+ *
+ * @param string $form_name Form namespace
+ *
+ * @return void
+ * @link http://docs.elgg.org/Tutorials/UI/StickyForms
+ * @since 1.8.0
+ */
+function elgg_clear_sticky_form($form_name) {
+ unset($_SESSION['sticky_forms'][$form_name]);
+}
+
+/**
+ * Has this form been made sticky?
+ *
+ * @param string $form_name Form namespace
+ *
+ * @return boolean
+ * @link http://docs.elgg.org/Tutorials/UI/StickyForms
+ * @since 1.8.0
+ */
+function elgg_is_sticky_form($form_name) {
+ return isset($_SESSION['sticky_forms'][$form_name]);
+}
+
+/**
+ * Get a specific sticky variable
+ *
+ * @param string $form_name The name of the form
+ * @param string $variable The name of the variable
+ * @param mixed $default Default value if the variable does not exist in sticky cache
+ * @param boolean $filter_result Filter for bad input if true
+ *
+ * @return mixed
+ *
+ * @todo should this filter the default value?
+ * @link http://docs.elgg.org/Tutorials/UI/StickyForms
+ * @since 1.8.0
+ */
+function elgg_get_sticky_value($form_name, $variable = '', $default = NULL, $filter_result = true) {
+ if (isset($_SESSION['sticky_forms'][$form_name][$variable])) {
+ $value = $_SESSION['sticky_forms'][$form_name][$variable];
+ if ($filter_result) {
+ // XSS filter result
+ $value = filter_tags($value);
+ }
+ return $value;
+ }
+ return $default;
+}
+
+/**
+ * Get all the values in a sticky form in an array
+ *
+ * @param string $form_name The name of the form
+ * @param bool $filter_result Filter for bad input if true
+ *
+ * @return array
+ * @since 1.8.0
+ */
+function elgg_get_sticky_values($form_name, $filter_result = true) {
+ if (!isset($_SESSION['sticky_forms'][$form_name])) {
+ return array();
+ }
+
+ $values = $_SESSION['sticky_forms'][$form_name];
+ if ($filter_result) {
+ foreach ($values as $key => $value) {
+ // XSS filter result
+ $values[$key] = filter_tags($value);
+ }
+ }
+ return $values;
+}
+
+/**
+ * Clear a specific sticky variable
+ *
+ * @param string $form_name The name of the form
+ * @param string $variable The name of the variable to clear
+ *
+ * @return void
+ * @link http://docs.elgg.org/Tutorials/UI/StickyForms
+ * @since 1.8.0
+ */
+function elgg_clear_sticky_value($form_name, $variable) {
+ unset($_SESSION['sticky_forms'][$form_name][$variable]);
+}
+
+/**
+ * Page handler for autocomplete endpoint.
+ *
+ * @todo split this into functions/objects, this is way too big
+ *
+ * /livesearch?q=<query>
+ *
+ * Other options include:
+ * match_on string all or array(groups|users|friends)
+ * match_owner int 0/1
+ * limit int default is 10
+ *
+ * @param array $page
+ * @return string JSON string is returned and then exit
+ * @access private
+ */
+function input_livesearch_page_handler($page) {
+ global $CONFIG;
+
+ // only return results to logged in users.
+ if (!$user = elgg_get_logged_in_user_entity()) {
+ exit;
+ }
+
+ if (!$q = get_input('term', get_input('q'))) {
+ exit;
+ }
+
+ $q = sanitise_string($q);
+
+ // replace mysql vars with escaped strings
+ $q = str_replace(array('_', '%'), array('\_', '\%'), $q);
+
+ $match_on = get_input('match_on', 'all');
+
+ if (!is_array($match_on)) {
+ $match_on = array($match_on);
+ }
+
+ // all = users and groups
+ if (in_array('all', $match_on)) {
+ $match_on = array('users', 'groups');
+ }
+
+ if (get_input('match_owner', false)) {
+ $owner_where = 'AND e.owner_guid = ' . $user->getGUID();
+ } else {
+ $owner_where = '';
+ }
+
+ $limit = sanitise_int(get_input('limit', 10));
+
+ // grab a list of entities and send them in json.
+ $results = array();
+ foreach ($match_on as $match_type) {
+ switch ($match_type) {
+ case 'users':
+ $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as ue, {$CONFIG->dbprefix}entities as e
+ WHERE e.guid = ue.guid
+ AND e.enabled = 'yes'
+ AND ue.banned = 'no'
+ AND (ue.name LIKE '$q%' OR ue.name LIKE '% $q%' OR ue.username LIKE '$q%')
+ LIMIT $limit
+ ";
+
+ if ($entities = get_data($query)) {
+ foreach ($entities as $entity) {
+ // @todo use elgg_get_entities (don't query in a loop!)
+ $entity = get_entity($entity->guid);
+ /* @var ElggUser $entity */
+ if (!$entity) {
+ continue;
+ }
+
+ if (in_array('groups', $match_on)) {
+ $value = $entity->guid;
+ } else {
+ $value = $entity->username;
+ }
+
+ $output = elgg_view_list_item($entity, array(
+ 'use_hover' => false,
+ 'class' => 'elgg-autocomplete-item',
+ ));
+
+ $icon = elgg_view_entity_icon($entity, 'tiny', array(
+ 'use_hover' => false,
+ ));
+
+ $result = array(
+ 'type' => 'user',
+ 'name' => $entity->name,
+ 'desc' => $entity->username,
+ 'guid' => $entity->guid,
+ 'label' => $output,
+ 'value' => $value,
+ 'icon' => $icon,
+ 'url' => $entity->getURL(),
+ );
+ $results[$entity->name . rand(1, 100)] = $result;
+ }
+ }
+ break;
+
+ case 'groups':
+ // don't return results if groups aren't enabled.
+ if (!elgg_is_active_plugin('groups')) {
+ continue;
+ }
+ $query = "SELECT * FROM {$CONFIG->dbprefix}groups_entity as ge, {$CONFIG->dbprefix}entities as e
+ WHERE e.guid = ge.guid
+ AND e.enabled = 'yes'
+ $owner_where
+ AND (ge.name LIKE '$q%' OR ge.name LIKE '% $q%' OR ge.description LIKE '% $q%')
+ LIMIT $limit
+ ";
+ if ($entities = get_data($query)) {
+ foreach ($entities as $entity) {
+ // @todo use elgg_get_entities (don't query in a loop!)
+ $entity = get_entity($entity->guid);
+ /* @var ElggGroup $entity */
+ if (!$entity) {
+ continue;
+ }
+
+ $output = elgg_view_list_item($entity, array(
+ 'use_hover' => false,
+ 'class' => 'elgg-autocomplete-item',
+ ));
+
+ $icon = elgg_view_entity_icon($entity, 'tiny', array(
+ 'use_hover' => false,
+ ));
+
+ $result = array(
+ 'type' => 'group',
+ 'name' => $entity->name,
+ 'desc' => strip_tags($entity->description),
+ 'guid' => $entity->guid,
+ 'label' => $output,
+ 'value' => $entity->guid,
+ 'icon' => $icon,
+ 'url' => $entity->getURL(),
+ );
+
+ $results[$entity->name . rand(1, 100)] = $result;
+ }
+ }
+ break;
+
+ case 'friends':
+ $query = "SELECT * FROM
+ {$CONFIG->dbprefix}users_entity as ue,
+ {$CONFIG->dbprefix}entity_relationships as er,
+ {$CONFIG->dbprefix}entities as e
+ WHERE er.relationship = 'friend'
+ AND er.guid_one = {$user->getGUID()}
+ AND er.guid_two = ue.guid
+ AND e.guid = ue.guid
+ AND e.enabled = 'yes'
+ AND ue.banned = 'no'
+ AND (ue.name LIKE '$q%' OR ue.name LIKE '% $q%' OR ue.username LIKE '$q%')
+ LIMIT $limit
+ ";
+
+ if ($entities = get_data($query)) {
+ foreach ($entities as $entity) {
+ // @todo use elgg_get_entities (don't query in a loop!)
+ $entity = get_entity($entity->guid);
+ /* @var ElggUser $entity */
+ if (!$entity) {
+ continue;
+ }
+
+ $output = elgg_view_list_item($entity, array(
+ 'use_hover' => false,
+ 'class' => 'elgg-autocomplete-item',
+ ));
+
+ $icon = elgg_view_entity_icon($entity, 'tiny', array(
+ 'use_hover' => false,
+ ));
+
+ $result = array(
+ 'type' => 'user',
+ 'name' => $entity->name,
+ 'desc' => $entity->username,
+ 'guid' => $entity->guid,
+ 'label' => $output,
+ 'value' => $entity->username,
+ 'icon' => $icon,
+ 'url' => $entity->getURL(),
+ );
+ $results[$entity->name . rand(1, 100)] = $result;
+ }
+ }
+ break;
+
+ default:
+ header("HTTP/1.0 400 Bad Request", true);
+ echo "livesearch: unknown match_on of $match_type";
+ exit;
+ break;
+ }
+ }
+
+ ksort($results);
+ header("Content-Type: application/json");
+ echo json_encode(array_values($results));
+ exit;
+}
+
+/**
+ * Register input functions and sanitize input
+ *
+ * @return void
+ * @access private
+ */
+function input_init() {
+ // register an endpoint for live search / autocomplete.
+ elgg_register_page_handler('livesearch', 'input_livesearch_page_handler');
+
+ if (ini_get_bool('magic_quotes_gpc')) {
+
+ /**
+ * do keys as well, cos array_map ignores them
+ *
+ * @param array $array Array of values
+ *
+ * @return array Sanitized array
+ */
+ function stripslashes_arraykeys($array) {
+ if (is_array($array)) {
+ $array2 = array();
+ foreach ($array as $key => $data) {
+ if ($key != stripslashes($key)) {
+ $array2[stripslashes($key)] = $data;
+ } else {
+ $array2[$key] = $data;
+ }
+ }
+ return $array2;
+ } else {
+ return $array;
+ }
+ }
+
+ /**
+ * Strip slashes on everything
+ *
+ * @param mixed $value The value to remove slashes from
+ *
+ * @return mixed
+ */
+ function stripslashes_deep($value) {
+ if (is_array($value)) {
+ $value = stripslashes_arraykeys($value);
+ $value = array_map('stripslashes_deep', $value);
+ } else {
+ $value = stripslashes($value);
+ }
+ return $value;
+ }
+
+ $_POST = stripslashes_arraykeys($_POST);
+ $_GET = stripslashes_arraykeys($_GET);
+ $_COOKIE = stripslashes_arraykeys($_COOKIE);
+ $_REQUEST = stripslashes_arraykeys($_REQUEST);
+
+ $_POST = array_map('stripslashes_deep', $_POST);
+ $_GET = array_map('stripslashes_deep', $_GET);
+ $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
+ $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
+ if (!empty($_SERVER['REQUEST_URI'])) {
+ $_SERVER['REQUEST_URI'] = stripslashes($_SERVER['REQUEST_URI']);
+ }
+ if (!empty($_SERVER['QUERY_STRING'])) {
+ $_SERVER['QUERY_STRING'] = stripslashes($_SERVER['QUERY_STRING']);
+ }
+ if (!empty($_SERVER['HTTP_REFERER'])) {
+ $_SERVER['HTTP_REFERER'] = stripslashes($_SERVER['HTTP_REFERER']);
+ }
+ if (!empty($_SERVER['PATH_INFO'])) {
+ $_SERVER['PATH_INFO'] = stripslashes($_SERVER['PATH_INFO']);
+ }
+ if (!empty($_SERVER['PHP_SELF'])) {
+ $_SERVER['PHP_SELF'] = stripslashes($_SERVER['PHP_SELF']);
+ }
+ if (!empty($_SERVER['PATH_TRANSLATED'])) {
+ $_SERVER['PATH_TRANSLATED'] = stripslashes($_SERVER['PATH_TRANSLATED']);
+ }
+ }
+}
+
+elgg_register_event_handler('init', 'system', 'input_init');