From 54a3c3e7e9e70c4770010e442e95f734200d03f9 Mon Sep 17 00:00:00 2001 From: brettp Date: Thu, 15 Oct 2009 04:41:46 +0000 Subject: Standardized gobs of files. git-svn-id: http://code.elgg.org/elgg/trunk@3548 36083f99-b078-4883-b0ff-0f9b5a30f544 --- engine/lib/calendar.php | 951 ++++++++-------- engine/lib/configuration.php | 404 +++---- engine/lib/cron.php | 106 +- engine/lib/exceptions.php | 321 +++--- engine/lib/export.php | 472 ++++---- engine/lib/extender.php | 851 +++++++------- engine/lib/filestore.php | 2469 ++++++++++++++++++++-------------------- engine/lib/group.php | 1723 ++++++++++++++-------------- engine/lib/input.php | 692 ++++++------ engine/lib/install.php | 233 ++-- engine/lib/languages.php | 480 ++++---- engine/lib/location.php | 492 ++++---- engine/lib/mb_wrapper.php | 113 +- engine/lib/memcache.php | 354 +++--- engine/lib/metadata.php | 1707 ++++++++++++++-------------- engine/lib/metastrings.php | 340 +++--- engine/lib/notification.php | 822 +++++++------- engine/lib/objects.php | 645 ++++++----- engine/lib/opendd.php | 691 ++++++------ engine/lib/pagehandler.php | 210 ++-- engine/lib/pageowner.php | 354 +++--- engine/lib/pam.php | 155 ++- engine/lib/ping.php | 88 +- engine/lib/plugins.php | 1380 +++++++++++------------ engine/lib/query.php | 449 ++++---- engine/lib/relationships.php | 1886 ++++++++++++++++--------------- engine/lib/river2.php | 548 +++++---- engine/lib/search.php | 88 +- engine/lib/sites.php | 1085 +++++++++--------- engine/lib/social.php | 233 ++-- engine/lib/statistics.php | 205 ++-- engine/lib/system_log.php | 559 ++++----- engine/lib/tags.php | 333 +++--- engine/lib/users.php | 2562 +++++++++++++++++++++--------------------- engine/lib/usersettings.php | 147 ++- engine/lib/version.php | 229 ++-- engine/lib/widgets.php | 228 ++-- 37 files changed, 12323 insertions(+), 12282 deletions(-) (limited to 'engine/lib') diff --git a/engine/lib/calendar.php b/engine/lib/calendar.php index 1f25eda44..a9d6dfadf 100644 --- a/engine/lib/calendar.php +++ b/engine/lib/calendar.php @@ -1,93 +1,96 @@ site_guid; - - $where = array(); - - if (is_array($type)) { - $tempwhere = ""; - if (sizeof($type)) + public function getCalendarEndTime(); +} + +/** + * Return a timestamp for the start of a given day (defaults today). + * + */ +function get_day_start($day = null, $month = null, $year = null) { + return mktime(0, 0, 0, $month, $day, $year); +} + +/** + * Return a timestamp for the end of a given day (defaults today). + * + */ +function get_day_end($day = null, $month = null, $year = null) { + return mktime(23, 59, 59, $month, $day, $year); +} + +/** + * Return the notable entities for a given time period. + * + * @param int $start_time The start time as a unix timestamp. + * @param int $end_time The end time as a unix timestamp. + * @param string $type The type of entity (eg "user", "object" etc) + * @param string $subtype The arbitrary subtype of the entity + * @param int $owner_guid The GUID of the owning user + * @param string $order_by The field to order by; by default, time_created desc + * @param int $limit The number of entities to return; 10 by default + * @param int $offset The indexing offset, 0 by default + * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param int|array $container_guid The container or containers to get entities from (default: all containers). + */ +function get_notable_entities($start_time, $end_time, $type = "", $subtype = "", $owner_guid = 0, $order_by = "asc", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid = null) { + global $CONFIG; + + if ($subtype === false || $subtype === null || $subtype === 0) { + return false; + } + + $start_time = (int)$start_time; + $end_time = (int)$end_time; + $order_by = sanitise_string($order_by); + $limit = (int)$limit; + $offset = (int)$offset; + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + $where = array(); + + if (is_array($type)) { + $tempwhere = ""; + if (sizeof($type)) { foreach($type as $typekey => $subtypearray) { foreach($subtypearray as $subtypeval) { $typekey = sanitise_string($typekey); @@ -98,397 +101,429 @@ } if (!empty($tempwhere)) $tempwhere .= " or "; $tempwhere .= "(e.type = '{$typekey}' and e.subtype = {$subtypeval})"; - } + } } - if (!empty($tempwhere)) $where[] = "({$tempwhere})"; - - } else { - - $type = sanitise_string($type); - $subtype = get_subtype_id($type, $subtype); - - if ($type != "") - $where[] = "e.type='$type'"; - if ($subtype!=="") - $where[] = "e.subtype=$subtype"; - } - - if ($owner_guid != "") { - if (!is_array($owner_guid)) { - $owner_array = array($owner_guid); - $owner_guid = (int) $owner_guid; - $where[] = "e.owner_guid = '$owner_guid'"; - } else if (sizeof($owner_guid) > 0) { - $owner_array = array_map('sanitise_int', $owner_guid); - // Cast every element to the owner_guid array to int - $owner_guid = implode(",",$owner_guid); // - $where[] = "e.owner_guid in ({$owner_guid})" ; // - } - if (is_null($container_guid)) { - $container_guid = $owner_array; - } + if (!empty($tempwhere)) { + $where[] = "({$tempwhere})"; } - - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - - if (!is_null($container_guid)) { - if (is_array($container_guid)) { - foreach($container_guid as $key => $val) $container_guid[$key] = (int) $val; - $where[] = "e.container_guid in (" . implode(",",$container_guid) . ")"; - } else { - $container_guid = (int) $container_guid; - $where[] = "e.container_guid = {$container_guid}"; - } - } - - // Add the calendar stuff - $cal_join = " - JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid - JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id - JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id - - JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid - JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id - JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id - "; - $where[] = "cal_start_name.string='calendar_start'"; - $where[] = "cal_start_value.string>=$start_time"; - $where[] = "cal_end_name.string='calendar_end'"; - $where[] = "cal_end_value.string <= $end_time"; - - - if (!$count) { - $query = "SELECT e.* from {$CONFIG->dbprefix}entities e $cal_join where "; - } else { - $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e $cal_join where "; + } else { + $type = sanitise_string($type); + $subtype = get_subtype_id($type, $subtype); + + if ($type != "") { + $where[] = "e.type='$type'"; } - foreach ($where as $w) - $query .= " $w and "; - - $query .= get_access_sql_suffix('e'); // Add access controls - - if (!$count) { - $query .= " order by n.calendar_start $order_by"; - if ($limit) $query .= " limit $offset, $limit"; // Add order and limit - $dt = get_data($query, "entity_row_to_elggstar"); - return $dt; - } else { - $total = get_data_row($query); - return $total->total; + + if ($subtype!=="") { + $where[] = "e.subtype=$subtype"; } - } - - /** - * Return the notable entities for a given time period based on an item of metadata. - * - * @param int $start_time The start time as a unix timestamp. - * @param int $end_time The end time as a unix timestamp. - * @param mixed $meta_name - * @param mixed $meta_value - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity. - * @param int $limit - * @param int $offset - * @param string $order_by Optional ordering. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) - * - * @return int|array A list of entities, or a count if $count is set to true - */ - function get_notable_entities_from_metadata($start_time, $end_time, $meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) - { - global $CONFIG; - - $meta_n = get_metastring_id($meta_name); - $meta_v = get_metastring_id($meta_value); - - $start_time = (int)$start_time; - $end_time = (int)$end_time; - $entity_type = sanitise_string($entity_type); - $entity_subtype = get_subtype_id($entity_type, $entity_subtype); - $limit = (int)$limit; - $offset = (int)$offset; - if ($order_by == "") $order_by = "e.time_created desc"; - $order_by = sanitise_string($order_by); - $site_guid = (int) $site_guid; - if ((is_array($owner_guid) && (count($owner_guid)))) { - foreach($owner_guid as $key => $guid) { - $owner_guid[$key] = (int) $guid; - } - } else { + + if ($owner_guid != "") { + if (!is_array($owner_guid)) { + $owner_array = array($owner_guid); $owner_guid = (int) $owner_guid; + $where[] = "e.owner_guid = '$owner_guid'"; + } else if (sizeof($owner_guid) > 0) { + $owner_array = array_map('sanitise_int', $owner_guid); + // Cast every element to the owner_guid array to int + $owner_guid = implode(",",$owner_guid); // + $where[] = "e.owner_guid in ({$owner_guid})" ; // } - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - //$access = get_access_list(); - - $where = array(); - - if ($entity_type!="") - $where[] = "e.type='$entity_type'"; - if ($entity_subtype) - $where[] = "e.subtype=$entity_subtype"; - if ($meta_name!="") - $where[] = "m.name_id='$meta_n'"; - if ($meta_value!="") - $where[] = "m.value_id='$meta_v'"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - if (is_array($owner_guid)) { - $where[] = "e.container_guid in (".implode(",",$owner_guid).")"; - } else if ($owner_guid > 0) - $where[] = "e.container_guid = {$owner_guid}"; - - // Add the calendar stuff - $cal_join = " - JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid - JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id - JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id - - JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid - JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id - JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id - "; - $where[] = "cal_start_name.string='calendar_start'"; - $where[] = "cal_start_value.string>=$start_time"; - $where[] = "cal_end_name.string='calendar_end'"; - $where[] = "cal_end_value.string <= $end_time"; - - if (!$count) { - $query = "SELECT distinct e.* "; - } else { - $query = "SELECT count(distinct e.guid) as total "; + if (is_null($container_guid)) { + $container_guid = $owner_array; } - - $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid $cal_join where"; - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); + } + + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + if (!is_null($container_guid)) { + if (is_array($container_guid)) { + foreach($container_guid as $key => $val) $container_guid[$key] = (int) $val; + $where[] = "e.container_guid in (" . implode(",",$container_guid) . ")"; } else { - if ($row = get_data_row($query)) - return $row->total; + $container_guid = (int) $container_guid; + $where[] = "e.container_guid = {$container_guid}"; } - return false; - } - - /** - * Return the notable entities for a given time period based on their relationship. - * - * @param int $start_time The start time as a unix timestamp. - * @param int $end_time The end time as a unix timestamp. - * @param string $relationship The relationship eg "friends_of" - * @param int $relationship_guid The guid of the entity to use query - * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" - * @param string $type - * @param string $subtype - * @param int $owner_guid - * @param string $order_by - * @param int $limit - * @param int $offset - * @param boolean $count Set to true if you want to count the number of entities instead (default false) - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @return array|int|false An array of entities, or the number of entities, or false on failure - */ - function get_noteable_entities_from_relationship($start_time, $end_time, $relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) - { - global $CONFIG; - - $start_time = (int)$start_time; - $end_time = (int)$end_time; - $relationship = sanitise_string($relationship); - $relationship_guid = (int)$relationship_guid; - $inverse_relationship = (bool)$inverse_relationship; - $type = sanitise_string($type); - $subtype = get_subtype_id($type, $subtype); - $owner_guid = (int)$owner_guid; - if ($order_by == "") $order_by = "time_created desc"; - $order_by = sanitise_string($order_by); - $limit = (int)$limit; - $offset = (int)$offset; - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - //$access = get_access_list(); - - $where = array(); - - if ($relationship!="") - $where[] = "r.relationship='$relationship'"; - if ($relationship_guid) - $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'"); - if ($type != "") - $where[] = "e.type='$type'"; - if ($subtype) - $where[] = "e.subtype=$subtype"; - if ($owner_guid != "") - $where[] = "e.container_guid='$owner_guid'"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - - // Add the calendar stuff - $cal_join = " - JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid - JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id - JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id - - JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid - JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id - JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id - "; - $where[] = "cal_start_name.string='calendar_start'"; - $where[] = "cal_start_value.string>=$start_time"; - $where[] = "cal_end_name.string='calendar_end'"; - $where[] = "cal_end_value.string <= $end_time"; - - // Select what we're joining based on the options - $joinon = "e.guid = r.guid_one"; - if (!$inverse_relationship) - $joinon = "e.guid = r.guid_two"; - - if ($count) { - $query = "SELECT count(distinct e.guid) as total "; - } else { - $query = "SELECT distinct e.* "; + + // Add the calendar stuff + $cal_join = " + JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid + JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id + JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id + + JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid + JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id + JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id + "; + $where[] = "cal_start_name.string='calendar_start'"; + $where[] = "cal_start_value.string>=$start_time"; + $where[] = "cal_end_name.string='calendar_end'"; + $where[] = "cal_end_value.string <= $end_time"; + + + if (!$count) { + $query = "SELECT e.* from {$CONFIG->dbprefix}entities e $cal_join where "; + } else { + $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e $cal_join where "; + } + foreach ($where as $w) { + $query .= " $w and "; + } + + $query .= get_access_sql_suffix('e'); // Add access controls + + if (!$count) { + $query .= " order by n.calendar_start $order_by"; + // Add order and limit + if ($limit) { + $query .= " limit $offset, $limit"; } - $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on $joinon $cal_join where "; - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); - } else { - if ($count = get_data_row($query)) { - return $count->total; - } + $dt = get_data($query, "entity_row_to_elggstar"); + + return $dt; + } else { + $total = get_data_row($query); + return $total->total; + } +} + +/** + * Return the notable entities for a given time period based on an item of metadata. + * + * @param int $start_time The start time as a unix timestamp. + * @param int $end_time The end time as a unix timestamp. + * @param mixed $meta_name + * @param mixed $meta_value + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity. + * @param int $limit + * @param int $offset + * @param string $order_by Optional ordering. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) + * + * @return int|array A list of entities, or a count if $count is set to true + */ +function get_notable_entities_from_metadata($start_time, $end_time, $meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) { + global $CONFIG; + + $meta_n = get_metastring_id($meta_name); + $meta_v = get_metastring_id($meta_value); + + $start_time = (int)$start_time; + $end_time = (int)$end_time; + $entity_type = sanitise_string($entity_type); + $entity_subtype = get_subtype_id($entity_type, $entity_subtype); + $limit = (int)$limit; + $offset = (int)$offset; + if ($order_by == "") { + $order_by = "e.time_created desc"; + } + $order_by = sanitise_string($order_by); + $site_guid = (int) $site_guid; + if ((is_array($owner_guid) && (count($owner_guid)))) { + foreach($owner_guid as $key => $guid) { + $owner_guid[$key] = (int) $guid; } - return false; + } else { + $owner_guid = (int) $owner_guid; } - - /** - * Get all entities for today. - * - * @param string $type The type of entity (eg "user", "object" etc) - * @param string $subtype The arbitrary subtype of the entity - * @param int $owner_guid The GUID of the owning user - * @param string $order_by The field to order by; by default, time_created desc - * @param int $limit The number of entities to return; 10 by default - * @param int $offset The indexing offset, 0 by default - * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @param int|array $container_guid The container or containers to get entities from (default: all containers). - */ - function get_todays_entities($type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid = null) - { - $day_start = get_day_start(); - $day_end = get_day_end(); - - return get_notable_entities($day_start, $day_end, $type, $subtype, $owner_guid, $order_by, $limit, $offset, $count, $site_guid, $container_guid); - } - - /** - * Get entities for today from metadata. - * - * @param mixed $meta_name - * @param mixed $meta_value - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity. - * @param int $limit - * @param int $offset - * @param string $order_by Optional ordering. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) - * - * @return int|array A list of entities, or a count if $count is set to true - */ - function get_todays_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) - { - $day_start = get_day_start(); - $day_end = get_day_end(); - - return get_notable_entities_from_metadata($day_start, $day_end, $meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, $order_by, $site_guid, $count); - } - - /** - * Get entities for today from a relationship - * - * @param string $relationship The relationship eg "friends_of" - * @param int $relationship_guid The guid of the entity to use query - * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" - * @param string $type - * @param string $subtype - * @param int $owner_guid - * @param string $order_by - * @param int $limit - * @param int $offset - * @param boolean $count Set to true if you want to count the number of entities instead (default false) - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @return array|int|false An array of entities, or the number of entities, or false on failure - */ - function get_todays_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) - { - $day_start = get_day_start(); - $day_end = get_day_end(); - - return get_notable_entities_from_relationship($day_start, $day_end, $relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, $order_by, $limit, $offset, $count, $site_guid); - } - - /** - * Returns a viewable list of entities for a given time period. - * - * @see elgg_view_entity_list - * - * @param int $start_time The start time as a unix timestamp. - * @param int $end_time The end time as a unix timestamp. - * @param string $type The type of entity (eg "user", "object" etc) - * @param string $subtype The arbitrary subtype of the entity - * @param int $owner_guid The GUID of the owning user - * @param int $limit The number of entities to display per page (default: 10) - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow gallery view - * @param true|false $pagination Display pagination? Default: true - * @return string A viewable list of entities - */ - function list_notable_entities($start_time, $end_time, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) { - - $offset = (int) get_input('offset'); - $count = get_notable_entities($start_time, $end_time, $type, $subtype, $owner_guid, "", $limit, $offset, true); - $entities = get_notable_entities($start_time, $end_time,$type, $subtype, $owner_guid, "", $limit, $offset); - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $navigation); - + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; } - - /** - * Return a list of today's entities. - * - * @see list_notable_entities - * - * @param string $type The type of entity (eg "user", "object" etc) - * @param string $subtype The arbitrary subtype of the entity - * @param int $owner_guid The GUID of the owning user - * @param int $limit The number of entities to display per page (default: 10) - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow gallery view - * @param true|false $pagination Display pagination? Default: true - * @return string A viewable list of entities - */ - function list_todays_entities($type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) { - - $day_start = get_day_start(); - $day_end = get_day_end(); - - return list_notable_entities($day_start, $day_end, $type, $subtype, $owner_guid, $limit, $fullview, $viewtypetoggle, $navigation); - } -?> \ No newline at end of file + + //$access = get_access_list(); + + $where = array(); + + if ($entity_type!="") { + $where[] = "e.type='$entity_type'"; + } + + if ($entity_subtype) { + $where[] = "e.subtype=$entity_subtype"; + } + + if ($meta_name!="") { + $where[] = "m.name_id='$meta_n'"; + } + + if ($meta_value!="") { + $where[] = "m.value_id='$meta_v'"; + } + + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + if (is_array($owner_guid)) { + $where[] = "e.container_guid in (".implode(",",$owner_guid).")"; + } else if ($owner_guid > 0) { + $where[] = "e.container_guid = {$owner_guid}"; + } + + // Add the calendar stuff + $cal_join = " + JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid + JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id + JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id + + JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid + JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id + JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id + "; + + $where[] = "cal_start_name.string='calendar_start'"; + $where[] = "cal_start_value.string>=$start_time"; + $where[] = "cal_end_name.string='calendar_end'"; + $where[] = "cal_end_value.string <= $end_time"; + + if (!$count) { + $query = "SELECT distinct e.* "; + } else { + $query = "SELECT count(distinct e.guid) as total "; + } + + $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid $cal_join where"; + foreach ($where as $w) { + $query .= " $w and "; + } + + // Add access controls + $query .= get_access_sql_suffix("e"); + $query .= ' and ' . get_access_sql_suffix("m"); + + if (!$count) { + // Add order and limit + $query .= " order by $order_by limit $offset, $limit"; + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($row = get_data_row($query)) { + return $row->total; + } + } + + return false; +} + +/** + * Return the notable entities for a given time period based on their relationship. + * + * @param int $start_time The start time as a unix timestamp. + * @param int $end_time The end time as a unix timestamp. + * @param string $relationship The relationship eg "friends_of" + * @param int $relationship_guid The guid of the entity to use query + * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" + * @param string $type + * @param string $subtype + * @param int $owner_guid + * @param string $order_by + * @param int $limit + * @param int $offset + * @param boolean $count Set to true if you want to count the number of entities instead (default false) + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @return array|int|false An array of entities, or the number of entities, or false on failure + */ +function get_noteable_entities_from_relationship($start_time, $end_time, $relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) { + global $CONFIG; + + $start_time = (int)$start_time; + $end_time = (int)$end_time; + $relationship = sanitise_string($relationship); + $relationship_guid = (int)$relationship_guid; + $inverse_relationship = (bool)$inverse_relationship; + $type = sanitise_string($type); + $subtype = get_subtype_id($type, $subtype); + $owner_guid = (int)$owner_guid; + if ($order_by == "") { + $order_by = "time_created desc"; + } + $order_by = sanitise_string($order_by); + $limit = (int)$limit; + $offset = (int)$offset; + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + //$access = get_access_list(); + + $where = array(); + + if ($relationship!="") { + $where[] = "r.relationship='$relationship'"; + } + if ($relationship_guid) { + $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'"); + } + if ($type != "") { + $where[] = "e.type='$type'"; + } + if ($subtype) { + $where[] = "e.subtype=$subtype"; + } + if ($owner_guid != "") { + $where[] = "e.container_guid='$owner_guid'"; + } + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + // Add the calendar stuff + $cal_join = " + JOIN {$CONFIG->dbprefix}metadata cal_start on e.guid=cal_start.entity_guid + JOIN {$CONFIG->dbprefix}metastrings cal_start_name on cal_start.name_id=cal_start_name.id + JOIN {$CONFIG->dbprefix}metastrings cal_start_value on cal_start.value_id=cal_start_value.id + + JOIN {$CONFIG->dbprefix}metadata cal_end on e.guid=cal_end.entity_guid + JOIN {$CONFIG->dbprefix}metastrings cal_end_name on cal_end.name_id=cal_end_name.id + JOIN {$CONFIG->dbprefix}metastrings cal_end_value on cal_end.value_id=cal_end_value.id + "; + $where[] = "cal_start_name.string='calendar_start'"; + $where[] = "cal_start_value.string>=$start_time"; + $where[] = "cal_end_name.string='calendar_end'"; + $where[] = "cal_end_value.string <= $end_time"; + + // Select what we're joining based on the options + $joinon = "e.guid = r.guid_one"; + if (!$inverse_relationship) { + $joinon = "e.guid = r.guid_two"; + } + + if ($count) { + $query = "SELECT count(distinct e.guid) as total "; + } else { + $query = "SELECT distinct e.* "; + } + $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on $joinon $cal_join where "; + foreach ($where as $w) { + $query .= " $w and "; + } + // Add access controls + $query .= get_access_sql_suffix("e"); + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; + } + } + return false; +} + +/** + * Get all entities for today. + * + * @param string $type The type of entity (eg "user", "object" etc) + * @param string $subtype The arbitrary subtype of the entity + * @param int $owner_guid The GUID of the owning user + * @param string $order_by The field to order by; by default, time_created desc + * @param int $limit The number of entities to return; 10 by default + * @param int $offset The indexing offset, 0 by default + * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param int|array $container_guid The container or containers to get entities from (default: all containers). + */ +function get_todays_entities($type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid = null) { + $day_start = get_day_start(); + $day_end = get_day_end(); + + return get_notable_entities($day_start, $day_end, $type, $subtype, $owner_guid, $order_by, $limit, $offset, $count, $site_guid, $container_guid); +} + +/** + * Get entities for today from metadata. + * + * @param mixed $meta_name + * @param mixed $meta_value + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity. + * @param int $limit + * @param int $offset + * @param string $order_by Optional ordering. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) + * + * @return int|array A list of entities, or a count if $count is set to true + */ +function get_todays_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) { + $day_start = get_day_start(); + $day_end = get_day_end(); + + return get_notable_entities_from_metadata($day_start, $day_end, $meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, $order_by, $site_guid, $count); +} + +/** + * Get entities for today from a relationship + * + * @param string $relationship The relationship eg "friends_of" + * @param int $relationship_guid The guid of the entity to use query + * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" + * @param string $type + * @param string $subtype + * @param int $owner_guid + * @param string $order_by + * @param int $limit + * @param int $offset + * @param boolean $count Set to true if you want to count the number of entities instead (default false) + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @return array|int|false An array of entities, or the number of entities, or false on failure + */ +function get_todays_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) { + $day_start = get_day_start(); + $day_end = get_day_end(); + + return get_notable_entities_from_relationship($day_start, $day_end, $relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, $order_by, $limit, $offset, $count, $site_guid); +} + +/** + * Returns a viewable list of entities for a given time period. + * + * @see elgg_view_entity_list + * + * @param int $start_time The start time as a unix timestamp. + * @param int $end_time The end time as a unix timestamp. + * @param string $type The type of entity (eg "user", "object" etc) + * @param string $subtype The arbitrary subtype of the entity + * @param int $owner_guid The GUID of the owning user + * @param int $limit The number of entities to display per page (default: 10) + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow gallery view + * @param true|false $pagination Display pagination? Default: true + * @return string A viewable list of entities + */ +function list_notable_entities($start_time, $end_time, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) { + $offset = (int) get_input('offset'); + $count = get_notable_entities($start_time, $end_time, $type, $subtype, $owner_guid, "", $limit, $offset, true); + $entities = get_notable_entities($start_time, $end_time,$type, $subtype, $owner_guid, "", $limit, $offset); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $navigation); +} + +/** + * Return a list of today's entities. + * + * @see list_notable_entities + * + * @param string $type The type of entity (eg "user", "object" etc) + * @param string $subtype The arbitrary subtype of the entity + * @param int $owner_guid The GUID of the owning user + * @param int $limit The number of entities to display per page (default: 10) + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow gallery view + * @param true|false $pagination Display pagination? Default: true + * @return string A viewable list of entities + */ +function list_todays_entities($type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) { + $day_start = get_day_start(); + $day_end = get_day_end(); + + return list_notable_entities($day_start, $day_end, $type, $subtype, $owner_guid, $limit, $fullview, $viewtypetoggle, $navigation); +} \ No newline at end of file diff --git a/engine/lib/configuration.php b/engine/lib/configuration.php index 9aa5d2174..17b3cd04a 100644 --- a/engine/lib/configuration.php +++ b/engine/lib/configuration.php @@ -1,213 +1,213 @@ site_id; - - return delete_data("delete from {$CONFIG->dbprefix}config where name='$name' and site_guid=$site_guid"); - } +/** + * Unset a config option. + * + * @param string $name The name of the field. + * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default). + * @return mixed + */ +function unset_config($name, $site_guid = 0) { + global $CONFIG; + + $name = mysql_real_escape_string($name); + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = (int) $CONFIG->site_id; + } + + return delete_data("delete from {$CONFIG->dbprefix}config where name='$name' and site_guid=$site_guid"); +} + +/** + * Sets a configuration value + * + * @param string $name The name of the configuration value + * @param string $value Its value + * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default) + * @return false|int 1 or false depending on success or failure + */ +function set_config($name, $value, $site_guid = 0) { + global $CONFIG; + + // Unset existing + unset_config($name,$site_guid); + + $name = mysql_real_escape_string($name); + $value = mysql_real_escape_string($value); + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = (int) $CONFIG->site_id; + } + $CONFIG->$name = $value; + $value = sanitise_string(serialize($value)); + + return insert_data("insert into {$CONFIG->dbprefix}config set name = '{$name}', value = '{$value}', site_guid = {$site_guid}"); +} + +/** + * Gets a configuration value + * + * @param string $name The name of the config value + * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default) + * @return mixed|false Depending on success + */ +function get_config($name, $site_guid = 0) { + global $CONFIG; - /** - * Sets a configuration value - * - * @param string $name The name of the configuration value - * @param string $value Its value - * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default) - * @return false|int 1 or false depending on success or failure - */ - function set_config($name, $value, $site_guid = 0) { - - global $CONFIG; - - // Unset existing - unset_config($name,$site_guid); - - $name = mysql_real_escape_string($name); - $value = mysql_real_escape_string($value); - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = (int) $CONFIG->site_id; - $CONFIG->$name = $value; - $value = sanitise_string(serialize($value)); - - return insert_data("insert into {$CONFIG->dbprefix}config set name = '{$name}', value = '{$value}', site_guid = {$site_guid}"); - + if (isset($CONFIG->$name)) { + return $CONFIG->$name; + } + $name = mysql_real_escape_string($name); + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = (int) $CONFIG->site_id; + } + if ($result = get_data_row("SELECT value FROM {$CONFIG->dbprefix}config + WHERE name = '{$name}' and site_guid = {$site_guid}")) { + $result = $result->value; + $result = unserialize($result->value); + $CONFIG->$name = $result; + return $result; + } + + return false; +} + +/** + * Gets all the configuration details in the config database for a given site. + * + * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default) + */ +function get_all_config($site_guid = 0) { + global $CONFIG; + + $site_guid = (int) $site_guid; + + if ($site_guid == 0) { + $site_guid = (int) $CONFIG->site_id; + } + + if ($result = get_data("SELECT * from {$CONFIG->dbprefix}config where site_guid = {$site_guid}")) { + foreach ($result as $r) { + $name = $r->name; + $value = $r->value; + $CONFIG->$name = unserialize($value); } - /** - * Gets a configuration value - * - * @param string $name The name of the config value - * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default) - * @return mixed|false Depending on success - */ - function get_config($name, $site_guid = 0) { - - global $CONFIG; - if (isset($CONFIG->$name)) - return $CONFIG->$name; - $name = mysql_real_escape_string($name); - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = (int) $CONFIG->site_id; - if ($result = get_data_row("SELECT value from {$CONFIG->dbprefix}config where name = '{$name}' and site_guid = {$site_guid}")) { - $result = $result->value; - $result = unserialize($result->value); - $CONFIG->$name = $result; - return $result; - } - return false; - + return true; + } + return false; +} + +/** + * If certain configuration elements don't exist, autodetect sensible defaults + * + * @uses $CONFIG The main configuration global + * + */ +function set_default_config() { + global $CONFIG; + + if (empty($CONFIG->path)) { + $CONFIG->path = str_replace("\\","/",dirname(dirname(dirname(__FILE__)))) . "/"; + } + + if (empty($CONFIG->viewpath)) { + $CONFIG->viewpath = $CONFIG->path . "views/"; + } + + if (empty($CONFIG->pluginspath)) { + $CONFIG->pluginspath = $CONFIG->path . "mod/"; + } + + if (empty($CONFIG->wwwroot)) { + /* + $CONFIG->wwwroot = "http://" . $_SERVER['SERVER_NAME']; + + $request = $_SERVER['REQUEST_URI']; + + if (strripos($request,"/") < (strlen($request) - 1)) { + // addressing a file directly, not a dir + $request = substr($request, 0, strripos($request,"/")+1); } - - /** - * Gets all the configuration details in the config database for a given site. - * - * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default) - */ - function get_all_config($site_guid = 0) - { - global $CONFIG; - - $site_guid = (int) $site_guid; - - if ($site_guid == 0) - $site_guid = (int) $CONFIG->site_id; - - if ($result = get_data("SELECT * from {$CONFIG->dbprefix}config where site_guid = {$site_guid}")) { - foreach ($result as $r) - { - $name = $r->name; - $value = $r->value; - $CONFIG->$name = unserialize($value); - } - - return true; - } - return false; + + $CONFIG->wwwroot .= $request; + */ + $pathpart = str_replace("//","/",str_replace($_SERVER['DOCUMENT_ROOT'],"",$CONFIG->path)); + if (substr($pathpart,0,1) != "/") { + $pathpart = "/" . $pathpart; } + $CONFIG->wwwroot = "http://" . $_SERVER['HTTP_HOST'] . $pathpart; + } + + if (empty($CONFIG->url)) { + $CONFIG->url = $CONFIG->wwwroot; + } + + if (empty($CONFIG->sitename)) { + $CONFIG->sitename = "New Elgg site"; + } + + if (empty($CONFIG->language)) { + $CONFIG->language = "en"; + } +} - /** - * If certain configuration elements don't exist, autodetect sensible defaults - * - * @uses $CONFIG The main configuration global - * - */ - function set_default_config() { - - global $CONFIG; - if (empty($CONFIG->path)) - $CONFIG->path = str_replace("\\","/",dirname(dirname(dirname(__FILE__)))) . "/"; - - if (empty($CONFIG->viewpath)) - $CONFIG->viewpath = $CONFIG->path . "views/"; - - if (empty($CONFIG->pluginspath)) - $CONFIG->pluginspath = $CONFIG->path . "mod/"; - - if (empty($CONFIG->wwwroot)) { - /* - $CONFIG->wwwroot = "http://" . $_SERVER['SERVER_NAME']; - - $request = $_SERVER['REQUEST_URI']; - - if (strripos($request,"/") < (strlen($request) - 1)) { - // addressing a file directly, not a dir - $request = substr($request, 0, strripos($request,"/")+1); - } - - $CONFIG->wwwroot .= $request; - */ - $pathpart = str_replace("//","/",str_replace($_SERVER['DOCUMENT_ROOT'],"",$CONFIG->path)); - if (substr($pathpart,0,1) != "/") $pathpart = "/" . $pathpart; - $CONFIG->wwwroot = "http://" . $_SERVER['HTTP_HOST'] . $pathpart; - - } - - if (empty($CONFIG->url)) - $CONFIG->url = $CONFIG->wwwroot; - - if (empty($CONFIG->sitename)) - $CONFIG->sitename = "New Elgg site"; - - if (empty($CONFIG->language)) - $CONFIG->language = "en"; +/** + * Function that provides some config initialisation on system init + * + */ +function configuration_init() { + global $CONFIG; + if (is_installed() || is_db_installed()) { + $path = datalist_get('path'); + if (!empty($path)) { + $CONFIG->path = $path; } - - /** - * Function that provides some config initialisation on system init - * - */ - - function configuration_init() { - - global $CONFIG; - - if (is_installed() || is_db_installed()) { - - $path = datalist_get('path'); - if (!empty($path)) - $CONFIG->path = $path; - $dataroot = datalist_get('dataroot'); - if (!empty($dataroot)) - $CONFIG->dataroot = $dataroot; - $simplecache_enabled = datalist_get('simplecache_enabled'); - if ($simplecache_enabled !== false) { - $CONFIG->simplecache_enabled = $simplecache_enabled; - } else { - $CONFIG->simplecache_enabled = 1; - } - $viewpath_cache_enabled = datalist_get('viewpath_cache_enabled'); - if ($viewpath_cache_enabled !== false) { - $CONFIG->viewpath_cache_enabled = $viewpath_cache_enabled; - } else { - $CONFIG->viewpath_cache_enabled = 1; - } - if (isset($CONFIG->site) && ($CONFIG->site instanceof ElggSite)) { - $CONFIG->wwwroot = $CONFIG->site->url; - $CONFIG->sitename = $CONFIG->site->name; - $CONFIG->sitedescription = $CONFIG->site->description; - $CONFIG->siteemail = $CONFIG->site->email; - } - $CONFIG->url = $CONFIG->wwwroot; - - // Load default settings from database - get_all_config(); - - return true; - } + $dataroot = datalist_get('dataroot'); + if (!empty($dataroot)) { + $CONFIG->dataroot = $dataroot; } - - /** - * Register config_init - */ - - register_elgg_event_handler('boot','system','configuration_init',10); - -?> \ No newline at end of file + $simplecache_enabled = datalist_get('simplecache_enabled'); + if ($simplecache_enabled !== false) { + $CONFIG->simplecache_enabled = $simplecache_enabled; + } else { + $CONFIG->simplecache_enabled = 1; + } + $viewpath_cache_enabled = datalist_get('viewpath_cache_enabled'); + if ($viewpath_cache_enabled !== false) { + $CONFIG->viewpath_cache_enabled = $viewpath_cache_enabled; + } else { + $CONFIG->viewpath_cache_enabled = 1; + } + if (isset($CONFIG->site) && ($CONFIG->site instanceof ElggSite)) { + $CONFIG->wwwroot = $CONFIG->site->url; + $CONFIG->sitename = $CONFIG->site->name; + $CONFIG->sitedescription = $CONFIG->site->description; + $CONFIG->siteemail = $CONFIG->site->email; + } + $CONFIG->url = $CONFIG->wwwroot; + + // Load default settings from database + get_all_config(); + + return true; + } +} + +/** + * Register config_init + */ + +register_elgg_event_handler('boot', 'system', 'configuration_init', 10); \ No newline at end of file diff --git a/engine/lib/cron.php b/engine/lib/cron.php index e991e49a2..b4952e2ee 100644 --- a/engine/lib/cron.php +++ b/engine/lib/cron.php @@ -1,61 +1,57 @@ path . "engine/handlers/cron_handler.php"); - } - else - forward(); - } +/** + * Initialisation + * + */ +function cron_init() { + // Register a pagehandler for cron + register_page_handler('cron','cron_page_handler'); +} +/** + * Cron handler for redirecting pages. + * + * @param unknown_type $page + */ +function cron_page_handler($page) { + global $CONFIG; - // Register a startup event - register_elgg_event_handler('init','system','cron_init'); + if ($page[0]) { + switch (strtolower($page[0])) { + case 'minute' : + case 'fiveminute' : + case 'fifteenmin' : + case 'halfhour' : + case 'hourly' : + case 'daily' : + case 'weekly' : + case 'monthly': + case 'yearly' : + case 'reboot' : + set_input('period', $page[0]); + break; + default : + throw new CronException(sprintf(elgg_echo('CronException:unknownperiod'), $page[0])); + } + + // Include cron handler + include($CONFIG->path . "engine/handlers/cron_handler.php"); + } else { + forward(); + } +} -?> \ No newline at end of file +// Register a startup event +register_elgg_event_handler('init','system','cron_init'); \ No newline at end of file diff --git a/engine/lib/exceptions.php b/engine/lib/exceptions.php index 95f2bfc82..ccf017062 100644 --- a/engine/lib/exceptions.php +++ b/engine/lib/exceptions.php @@ -1,162 +1,161 @@ - * @link http://elgg.org/ - */ - - // Top level ////////////////////////////////////////////////////////////////////////////// - - /** - * IOException - * An IO Exception, throw when an IO Exception occurs. Subclass for specific IO Exceptions. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class IOException extends Exception {} - - /** - * ClassException - * A class Exception, throw when there is a class error. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class ClassException extends Exception {} - - /** - * ConfigurationException - * There is a configuration error - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class ConfigurationException extends Exception {} - - /** - * SecurityException - * An Security Exception, throw when a Security Exception occurs. Subclass for specific Security Execeptions (access problems etc) - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class SecurityException extends Exception {} - - /** - * ClassNotFoundException - * An database exception, throw when a database exception happens, subclass if more detail is needed. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class DatabaseException extends Exception {} - - /** - * APIException - * The API Exception class, thrown by the API layer when an API call has an issue. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class APIException extends Exception {} - - /** - * CallException - * An exception thrown when there is a problem calling something. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class CallException extends Exception {} - - /** - * Data format exception - * An exception thrown when there is a problem in the format of some data. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class DataFormatException extends Exception {} - - // Class exceptions /////////////////////////////////////////////////////////////////////// - - /** - * InvalidClassException - * An invalid class Exception, throw when a class is invalid. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class InvalidClassException extends ClassException {} - - /** - * ClassNotFoundException - * An Class not found Exception, throw when an class can not be found occurs. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class ClassNotFoundException extends ClassException {} - - // Configuration exceptions /////////////////////////////////////////////////////////////// - - /** - * InstallationException - * Thrown when there is a major problem with the installation. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class InstallationException extends ConfigurationException {} - - // Call exceptions //////////////////////////////////////////////////////////////////////// - - /** - * NotImplementedException - * Thrown when a method or function has not been implemented, primarily used in development... you should - * not see these! - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class NotImplementedException extends CallException {} - - /** - * InvalidParameterException - * A parameter is invalid. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class InvalidParameterException extends CallException {} - - // Installation exception ///////////////////////////////////////////////////////////////// - - /** - * RegistrationException - * Could not register a new user for whatever reason. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Exceptions - */ - class RegistrationException extends InstallationException {} -?> \ No newline at end of file +/** + * Exceptions. + * Define some globally useful exception classes. + * + * @package Elgg + * @subpackage Exceptions + * @author Curverider Ltd + * @link http://elgg.org/ + */ + +// Top level ////////////////////////////////////////////////////////////////////////////// + +/** + * IOException + * An IO Exception, throw when an IO Exception occurs. Subclass for specific IO Exceptions. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class IOException extends Exception {} + +/** + * ClassException + * A class Exception, throw when there is a class error. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class ClassException extends Exception {} + +/** + * ConfigurationException + * There is a configuration error + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class ConfigurationException extends Exception {} + +/** + * SecurityException + * An Security Exception, throw when a Security Exception occurs. Subclass for specific Security Execeptions (access problems etc) + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class SecurityException extends Exception {} + +/** + * ClassNotFoundException + * An database exception, throw when a database exception happens, subclass if more detail is needed. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class DatabaseException extends Exception {} + +/** + * APIException + * The API Exception class, thrown by the API layer when an API call has an issue. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class APIException extends Exception {} + +/** + * CallException + * An exception thrown when there is a problem calling something. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class CallException extends Exception {} + +/** + * Data format exception + * An exception thrown when there is a problem in the format of some data. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class DataFormatException extends Exception {} + +// Class exceptions /////////////////////////////////////////////////////////////////////// + +/** + * InvalidClassException + * An invalid class Exception, throw when a class is invalid. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class InvalidClassException extends ClassException {} + +/** + * ClassNotFoundException + * An Class not found Exception, throw when an class can not be found occurs. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class ClassNotFoundException extends ClassException {} + +// Configuration exceptions /////////////////////////////////////////////////////////////// + +/** + * InstallationException + * Thrown when there is a major problem with the installation. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class InstallationException extends ConfigurationException {} + +// Call exceptions //////////////////////////////////////////////////////////////////////// + +/** + * NotImplementedException + * Thrown when a method or function has not been implemented, primarily used in development... you should + * not see these! + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class NotImplementedException extends CallException {} + +/** + * InvalidParameterException + * A parameter is invalid. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class InvalidParameterException extends CallException {} + +// Installation exception ///////////////////////////////////////////////////////////////// + +/** + * RegistrationException + * Could not register a new user for whatever reason. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Exceptions + */ +class RegistrationException extends InstallationException {} \ No newline at end of file diff --git a/engine/lib/export.php b/engine/lib/export.php index 0e487faab..e3acace5f 100644 --- a/engine/lib/export.php +++ b/engine/lib/export.php @@ -1,262 +1,256 @@ guid); - else if ($object instanceof ElggExtender) { - $type = $object->type; - if ($type == 'volatile') - $uuid = guid_to_uuid($object->entity_guid). $type . "/{$object->name}/"; - else - $uuid = guid_to_uuid($object->entity_guid). $type . "/{$object->id}/"; - - return $uuid; - } else if ($object instanceof ElggRelationship) { - return guid_to_uuid($object->guid_one) . "relationship/{$object->id}/"; + public function import(ODD $data); +} + +/** + * Export exception + * + * @package Elgg + * @subpackage Exceptions + * + */ +class ExportException extends DataFormatException {} + +/** + * Import exception + * + * @package Elgg + * @subpackage Exceptions + */ +class ImportException extends DataFormatException {} + +/** + * Get a UUID from a given object. + * + * @param $object The object either an ElggEntity, ElggRelationship or ElggExtender + * @return the UUID or false + */ +function get_uuid_from_object($object) { + if ($object instanceof ElggEntity) { + return guid_to_uuid($object->guid); + } else if ($object instanceof ElggExtender) { + $type = $object->type; + if ($type == 'volatile') { + $uuid = guid_to_uuid($object->entity_guid). $type . "/{$object->name}/"; + } else { + $uuid = guid_to_uuid($object->entity_guid). $type . "/{$object->id}/"; } - - - return false; + + return $uuid; + } else if ($object instanceof ElggRelationship) { + return guid_to_uuid($object->guid_one) . "relationship/{$object->id}/"; } - - /** - * Generate a UUID from a given GUID. - * - * @param int $guid The GUID of an object. - */ - function guid_to_uuid($guid) - { - global $CONFIG; - - return $CONFIG->wwwroot . "export/opendd/$guid/"; + + return false; +} + +/** + * Generate a UUID from a given GUID. + * + * @param int $guid The GUID of an object. + */ +function guid_to_uuid($guid) { + global $CONFIG; + + return $CONFIG->wwwroot . "export/opendd/$guid/"; +} + +/** + * Test to see if a given uuid is for this domain, returning true if so. + * @param $uuid + * @return bool + */ +function is_uuid_this_domain($uuid) { + global $CONFIG; + + if (strpos($uuid, $CONFIG->wwwroot) === 0) { + return true; } - - /** - * Test to see if a given uuid is for this domain, returning true if so. - * @param $uuid - * @return bool - */ - function is_uuid_this_domain($uuid) - { - global $CONFIG; - - if (strpos($uuid, $CONFIG->wwwroot) === 0) - return true; - - return false; + + return false; +} + +/** + * This function attempts to retrieve a previously imported entity via its UUID. + * + * @param $uuid + */ +function get_entity_from_uuid($uuid) { + $uuid = sanitise_string($uuid); + + $entities = get_entities_from_metadata("import_uuid", $uuid); + + if ($entities) { + return $entities[0]; } - - /** - * This function attempts to retrieve a previously imported entity via its UUID. - * - * @param $uuid - */ - function get_entity_from_uuid($uuid) - { - $uuid = sanitise_string($uuid); - - $entities = get_entities_from_metadata("import_uuid", $uuid); - - if ($entities) - return $entities[0]; - - return false; + + return false; +} + +/** + * Tag a previously created guid with the uuid it was imported on. + * + * @param int $guid + * @param string $uuid + */ +function add_uuid_to_guid($guid, $uuid) { + $guid = (int)$guid; + $uuid = sanitise_string($uuid); + + return create_metadata($guid, "import_uuid", $uuid); +} + + +$IMPORTED_DATA = array(); +$IMPORTED_OBJECT_COUNTER = 0; + +/** + * This function processes an element, passing elements to the plugin stack to see if someone will + * process it. + * + * If nobody processes the top level element, the sub level elements are processed. + * + * @param ODD $odd The odd element to process + */ +function __process_element(ODD $odd) { + global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER; + + // See if anyone handles this element, return true if it is. + if ($odd) { + $handled = trigger_plugin_hook("import", "all", array("element" => $odd), $to_be_serialised); } - - /** - * Tag a previously created guid with the uuid it was imported on. - * - * @param int $guid - * @param string $uuid - */ - function add_uuid_to_guid($guid, $uuid) - { - $guid = (int)$guid; - $uuid = sanitise_string($uuid); - - return create_metadata($guid, "import_uuid", $uuid); + + // If not, then see if any of its sub elements are handled + if ($handled) { + // Increment validation counter + $IMPORTED_OBJECT_COUNTER ++; + // Return the constructed object + $IMPORTED_DATA[] = $handled; + + return true; } - - + + return false; +} + +function exportAsArray($guid) { + $guid = (int)$guid; + + // Initialise the array + $to_be_serialised = array(); + + // Trigger a hook to + $to_be_serialised = trigger_plugin_hook("export", "all", array("guid" => $guid), $to_be_serialised); + + // Sanity check + if ((!is_array($to_be_serialised)) || (count($to_be_serialised)==0)) { + throw new ExportException(sprintf(elgg_echo('ExportException:NoSuchEntity'), $guid)); + } + + return $to_be_serialised; +} + +/** + * Export a GUID. + * + * This function exports a GUID and all information related to it in an XML format. + * + * This function makes use of the "serialise" plugin hook, which is passed an array to which plugins + * should add data to be serialised to. + * + * @see ElggEntity for an example of its usage. + * @param int $guid The GUID. + * @param ODDWrapperFactory $wrapper Optional wrapper permitting the export process to embed ODD in other document formats. + * @return xml + */ +function export($guid) { + $odd = new ODDDocument(exportAsArray($guid)); + + return ODD_Export($odd); +} + +/** + * Import an XML serialisation of an object. + * This will make a best attempt at importing a given xml doc. + * + * @param string $xml + * @return bool + * @throws Exception if there was a problem importing the data. + */ +function import($xml) { + global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER; + $IMPORTED_DATA = array(); $IMPORTED_OBJECT_COUNTER = 0; - - /** - * This function processes an element, passing elements to the plugin stack to see if someone will - * process it. - * - * If nobody processes the top level element, the sub level elements are processed. - * - * @param ODD $odd The odd element to process - */ - function __process_element(ODD $odd) - { - global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER; - - // See if anyone handles this element, return true if it is. - if ($odd) - $handled = trigger_plugin_hook("import", "all", array("element" => $odd), $to_be_serialised); - - // If not, then see if any of its sub elements are handled - if ($handled) - { - $IMPORTED_OBJECT_COUNTER ++; // Increment validation counter - $IMPORTED_DATA[] = $handled; // Return the constructed object - - return true; - } - - return false; - } - - function exportAsArray($guid) - { - - $guid = (int)$guid; - - // Initialise the array - $to_be_serialised = array(); - - // Trigger a hook to - $to_be_serialised = trigger_plugin_hook("export", "all", array("guid" => $guid), $to_be_serialised); - - // Sanity check - if ((!is_array($to_be_serialised)) || (count($to_be_serialised)==0)) throw new ExportException(sprintf(elgg_echo('ExportException:NoSuchEntity'), $guid)); - - return $to_be_serialised; - } - - /** - * Export a GUID. - * - * This function exports a GUID and all information related to it in an XML format. - * - * This function makes use of the "serialise" plugin hook, which is passed an array to which plugins - * should add data to be serialised to. - * - * @see ElggEntity for an example of its usage. - * @param int $guid The GUID. - * @param ODDWrapperFactory $wrapper Optional wrapper permitting the export process to embed ODD in other document formats. - * @return xml - */ - function export($guid) - { - $odd = new ODDDocument(exportAsArray($guid)); - - return ODD_Export($odd); + + $document = ODD_Import($xml); + if (!$document) { + throw new ImportException(elgg_echo('ImportException:NoODDElements')); } - - /** - * Import an XML serialisation of an object. - * This will make a best attempt at importing a given xml doc. - * - * @param string $xml - * @return bool - * @throws Exception if there was a problem importing the data. - */ - function import($xml) - { - global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER; - - $IMPORTED_DATA = array(); - $IMPORTED_OBJECT_COUNTER = 0; - - $document = ODD_Import($xml); - if (!$document) - throw new ImportException(elgg_echo('ImportException:NoODDElements')); - - foreach ($document as $element) - __process_element($element); - - if ($IMPORTED_OBJECT_COUNTER!= count($IMPORTED_DATA)) - throw new ImportException(elgg_echo('ImportException:NotAllImported')); - - return true; + + foreach ($document as $element) { + __process_element($element); } - - /** - * Register the OpenDD import action - */ - function export_init() - { - global $CONFIG; - - register_action("import/opendd", false); + if ($IMPORTED_OBJECT_COUNTER!= count($IMPORTED_DATA)) { + throw new ImportException(elgg_echo('ImportException:NotAllImported')); } - - // Register a startup event - register_elgg_event_handler('init','system','export_init',100); -?> \ No newline at end of file + + return true; +} + + +/** + * Register the OpenDD import action + */ +function export_init() { + global $CONFIG; + + register_action("import/opendd", false); +} + +// Register a startup event +register_elgg_event_handler('init', 'system', 'export_init', 100); \ No newline at end of file diff --git a/engine/lib/extender.php b/engine/lib/extender.php index 456a1f778..cbcdd6eb7 100644 --- a/engine/lib/extender.php +++ b/engine/lib/extender.php @@ -1,450 +1,469 @@ attributes[$name])) { - - // Sanitise value if necessary - if ($name=='value') - { - switch ($this->attributes['value_type']) - { - case 'integer' : return (int)$this->attributes['value']; - //case 'tag' : - //case 'file' : - case 'text' : return ($this->attributes['value']); - - default : throw new InstallationException(sprintf(elgg_echo('InstallationException:TypeNotSupported'), $this->attributes['value_type'])); - } + protected function get($name) { + if (isset($this->attributes[$name])) { + // Sanitise value if necessary + if ($name=='value') { + switch ($this->attributes['value_type']) { + case 'integer' : + return (int)$this->attributes['value']; + + //case 'tag' : + //case 'file' : + case 'text' : + return ($this->attributes['value']); + + default : + throw new InstallationException(sprintf(elgg_echo('InstallationException:TypeNotSupported'), $this->attributes['value_type'])); } - - return $this->attributes[$name]; } - return null; - } - - /** - * Set an attribute - * - * @param string $name - * @param mixed $value - * @param string $value_type - * @return boolean - */ - protected function set($name, $value, $value_type = "") { - - $this->attributes[$name] = $value; - if ($name == 'value') - $this->attributes['value_type'] = detect_extender_valuetype($value, $value_type); - - return true; - } - - /** - * Return the owner of this annotation. - * - * @return mixed - */ - public function getOwner() - { - return $this->owner_guid; - } - /** - * Return the owner entity - * - * @return mixed - */ - public function getOwnerEntity() - { - return get_user($this->owner_guid); + return $this->attributes[$name]; } - - /** - * Returns the entity this is attached to - * - * @return ElggEntity The enttiy - */ - public function getEntity() { - return get_entity($this->entity_guid); - } - - /** - * Save this data to the appropriate database table. - */ - abstract public function save(); - - /** - * Delete this data. - */ - abstract public function delete(); - - /** - * Determines whether or not the specified user can edit this - * - * @param int $user_guid The GUID of the user (defaults to currently logged in user) - * @return true|false - */ - public function canEdit($user_guid = 0) { - return can_edit_extender($this->id,$this->type,$user_guid); - } - - /** - * Return a url for this extender. - * - * @return string - */ - public abstract function getURL(); - - // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// - - /** - * Return an array of fields which can be exported. - */ - public function getExportableValues() - { - return array( - 'id', - 'entity_guid', - 'name', - 'value', - 'value_type', - 'owner_guid', - 'type', - ); - } - - /** - * Export this object - * - * @return array - */ - public function export() - { - $uuid = get_uuid_from_object($this); - - $meta = new ODDMetadata($uuid, guid_to_uuid($this->entity_guid), $this->attributes['name'], $this->attributes['value'], $this->attributes['type'], guid_to_uuid($this->owner_guid)); - $meta->setAttribute('published', date("r", $this->time_created)); - - return $meta; - } - - // SYSTEM LOG INTERFACE //////////////////////////////////////////////////////////// - - /** - * Return an identification for the object for storage in the system log. - * This id must be an integer. - * - * @return int - */ - public function getSystemLogID() { return $this->id; } - - /** - * Return the class name of the object. - */ - public function getClassName() { return get_class($this); } - - /** - * Return the GUID of the owner of this object. - */ - public function getObjectOwnerGUID() { return $this->owner_guid; } - - /** - * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc - */ - public function getType() { return $this->type; } - - /** - * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type. - */ - public function getSubtype() { return $this->name; } - - - // ITERATOR INTERFACE ////////////////////////////////////////////////////////////// - /* - * This lets an entity's attributes be displayed using foreach as a normal array. - * Example: http://www.sitepoint.com/print/php5-standard-library - */ - - private $valid = FALSE; - - function rewind() - { - $this->valid = (FALSE !== reset($this->attributes)); - } - - function current() - { - return current($this->attributes); - } - - function key() - { - return key($this->attributes); - } - - function next() - { - $this->valid = (FALSE !== next($this->attributes)); - } - - function valid() - { - return $this->valid; - } - - // ARRAY ACCESS INTERFACE ////////////////////////////////////////////////////////// - /* - * This lets an entity's attributes be accessed like an associative array. - * Example: http://www.sitepoint.com/print/php5-standard-library - */ - - function offsetSet($key, $value) - { - if ( array_key_exists($key, $this->attributes) ) { - $this->attributes[$key] = $value; - } - } - - function offsetGet($key) - { - if ( array_key_exists($key, $this->attributes) ) { - return $this->attributes[$key]; - } - } - - function offsetUnset($key) - { - if ( array_key_exists($key, $this->attributes) ) { - $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects - } - } - - function offsetExists($offset) - { - return array_key_exists($offset, $this->attributes); - } - } - + return null; + } + /** - * Detect the value_type for a given value. - * Currently this is very crude. - * - * TODO: Make better! + * Set an attribute * + * @param string $name * @param mixed $value - * @param string $value_type If specified, overrides the detection. - * @return string + * @param string $value_type + * @return boolean */ - function detect_extender_valuetype($value, $value_type = "") - { - if ($value_type!="") - return $value_type; - - // This is crude - if (is_int($value)) return 'integer'; - if (is_numeric($value)) return 'text'; // Catch floating point values which are not integer - - return 'text'; + protected function set($name, $value, $value_type = "") { + $this->attributes[$name] = $value; + if ($name == 'value') { + $this->attributes['value_type'] = detect_extender_valuetype($value, $value_type); + } + + return true; } - + /** - * Utility function used by import_extender_plugin_hook() to process an ODDMetaData and add it to an entity. - * This function does not hit ->save() on the entity (this lets you construct in memory) + * Return the owner of this annotation. * - * @param ElggEntity The entity to add the data to. - * @param ODDMetaData $element The OpenDD element - * @return bool + * @return mixed */ - function oddmetadata_to_elggextender(ElggEntity $entity, ODDMetaData $element) - { - // Get the type of extender (metadata, type, attribute etc) - $type = $element->getAttribute('type'); - $attr_name = $element->getAttribute('name'); - $attr_val = $element->getBody(); - - switch ($type) - { - case 'volatile' : break; // Ignore volatile items - case 'annotation' : - $entity->annotate($attr_name, $attr_val); - break; - case 'metadata' : - $entity->setMetaData($attr_name, $attr_val, "", true); - break; - default : // Anything else assume attribute - $entity->set($attr_name, $attr_val); - } - - // Set time if appropriate - $attr_time = $element->getAttribute('published'); - if ($attr_time) - $entity->set('time_updated', $attr_time); - - return true; + public function getOwner() { + return $this->owner_guid; } - + /** - * Handler called by trigger_plugin_hook on the "import" event. + * Return the owner entity + * + * @return mixed */ - function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params) - { - $element = $params['element']; - - $tmp = NULL; - - if ($element instanceof ODDMetaData) - { - // Recall entity - $entity_uuid = $element->getAttribute('entity_uuid'); - $entity = get_entity_from_uuid($entity_uuid); - if (!$entity) - throw new ImportException(sprintf(elgg_echo('ImportException:GUIDNotFound'), $entity_uuid)); - - oddmetadata_to_elggextender($entity, $element); - - // Save - if (!$entity->save()) - throw new ImportException(sprintf(elgg_echo('ImportException:ProblemUpdatingMeta'), $attr_name, $entity_uuid)); - - return true; - } + public function getOwnerEntity() { + return get_user($this->owner_guid); + } + + /** + * Returns the entity this is attached to + * + * @return ElggEntity The enttiy + */ + public function getEntity() { + return get_entity($this->entity_guid); } - + /** - * Determines whether or not the specified user can edit the specified piece of extender + * Save this data to the appropriate database table. + */ + abstract public function save(); + + /** + * Delete this data. + */ + abstract public function delete(); + + /** + * Determines whether or not the specified user can edit this * - * @param int $extender_id The ID of the piece of extender - * @param string $type 'metadata' or 'annotation' - * @param int $user_guid The GUID of the user + * @param int $user_guid The GUID of the user (defaults to currently logged in user) * @return true|false */ - function can_edit_extender($extender_id, $type, $user_guid = 0) { - - if (!isloggedin()) - return false; - - $user_guid = (int)$user_guid; - $user = get_entity($user_guid); - if (!$user) $user = get_loggedin_user(); - - $functionname = "get_{$type}"; - if (is_callable($functionname)) { - $extender = $functionname($extender_id); - } else return false; - - if (!is_a($extender,"ElggExtender")) return false; - - // If the owner is the specified user, great! They can edit. - if ($extender->getOwner() == $user->getGUID()) return true; - - // If the user can edit the entity this is attached to, great! They can edit. - if (can_edit_entity($extender->entity_guid,$user->getGUID())) return true; - - // Trigger plugin hooks - return trigger_plugin_hook('permissions_check',$type,array('entity' => $entity, 'user' => $user),false); - - } - + public function canEdit($user_guid = 0) { + return can_edit_extender($this->id,$this->type,$user_guid); + } + /** - * Sets the URL handler for a particular extender type and name. - * It is recommended that you do not call this directly, instead use one of the wrapper functions in the - * subtype files. + * Return a url for this extender. * - * @param string $function_name The function to register - * @param string $extender_type Extender type - * @param string $extender_name The name of the extender - * @return true|false Depending on success + * @return string */ - function register_extender_url_handler($function_name, $extender_type = "all", $extender_name = "all") { - global $CONFIG; - - if (!is_callable($function_name)) return false; - - if (!isset($CONFIG->extender_url_handler)) { - $CONFIG->extender_url_handler = array(); - } - if (!isset($CONFIG->extender_url_handler[$extender_type])) { - $CONFIG->extender_url_handler[$extender_type] = array(); - } - $CONFIG->extender_url_handler[$extender_type][$extender_name] = $function_name; - - return true; - + public abstract function getURL(); + + // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// + + /** + * Return an array of fields which can be exported. + */ + public function getExportableValues() { + return array( + 'id', + 'entity_guid', + 'name', + 'value', + 'value_type', + 'owner_guid', + 'type', + ); } - + /** - * Get the URL of a given elgg extender. - * Used by get_annotation_url and get_metadata_url. + * Export this object * - * @param ElggExtender $extender + * @return array */ - function get_extender_url(ElggExtender $extender) - { - global $CONFIG; - - $view = elgg_get_viewtype(); - - $guid = $extender->entity_guid; - $type = $extender->type; - - $url = ""; - - $function = ""; - if (isset($CONFIG->extender_url_handler[$type][$extender->name])) - $function = $CONFIG->extender_url_handler[$type][$extender->name]; - if (isset($CONFIG->extender_url_handler[$type]['all'])) - $function = $CONFIG->extender_url_handler[$type]['all']; - if (isset($CONFIG->extender_url_handler['all']['all'])) - $function = $CONFIG->extender_url_handler['all']['all']; - - if (is_callable($function)) { - $url = $function($extender); + public function export() { + $uuid = get_uuid_from_object($this); + + $meta = new ODDMetadata($uuid, guid_to_uuid($this->entity_guid), $this->attributes['name'], $this->attributes['value'], $this->attributes['type'], guid_to_uuid($this->owner_guid)); + $meta->setAttribute('published', date("r", $this->time_created)); + + return $meta; + } + + // SYSTEM LOG INTERFACE //////////////////////////////////////////////////////////// + + /** + * Return an identification for the object for storage in the system log. + * This id must be an integer. + * + * @return int + */ + public function getSystemLogID() { + return $this->id; + } + + /** + * Return the class name of the object. + */ + public function getClassName() { + return get_class($this); + } + + /** + * Return the GUID of the owner of this object. + */ + public function getObjectOwnerGUID() { + return $this->owner_guid; + } + + /** + * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc + */ + public function getType() { + return $this->type; + } + + /** + * Return a subtype. For metadata & annotations this is the 'name' and + * for relationship this is the relationship type. + */ + public function getSubtype() { + return $this->name; + } + + + // ITERATOR INTERFACE ////////////////////////////////////////////////////////////// + /* + * This lets an entity's attributes be displayed using foreach as a normal array. + * Example: http://www.sitepoint.com/print/php5-standard-library + */ + + private $valid = FALSE; + + function rewind() { + $this->valid = (FALSE !== reset($this->attributes)); + } + + function current() { + return current($this->attributes); + } + + function key() { + return key($this->attributes); + } + + function next() { + $this->valid = (FALSE !== next($this->attributes)); + } + + function valid() { + return $this->valid; + } + + // ARRAY ACCESS INTERFACE ////////////////////////////////////////////////////////// + /* + * This lets an entity's attributes be accessed like an associative array. + * Example: http://www.sitepoint.com/print/php5-standard-library + */ + + function offsetSet($key, $value) { + if ( array_key_exists($key, $this->attributes) ) { + $this->attributes[$key] = $value; + } + } + + function offsetGet($key) { + if ( array_key_exists($key, $this->attributes) ) { + return $this->attributes[$key]; } - - if ($url == "") { - $nameid = $extender->id; - if ($type == 'volatile') - $nameid== $extender->name; - $url = $CONFIG->wwwroot . "export/$view/$guid/$type/$nameid/"; - } - return $url; - } - - /** Register the hook */ - register_plugin_hook("import", "all", "import_extender_plugin_hook", 2); - -?> + } + + function offsetUnset($key) { + if ( array_key_exists($key, $this->attributes) ) { + // Full unsetting is dangerious for our objects + $this->attributes[$key] = ""; + } + } + + function offsetExists($offset) { + return array_key_exists($offset, $this->attributes); + } +} + +/** + * Detect the value_type for a given value. + * Currently this is very crude. + * + * TODO: Make better! + * + * @param mixed $value + * @param string $value_type If specified, overrides the detection. + * @return string + */ +function detect_extender_valuetype($value, $value_type = "") { + if ($value_type!="") { + return $value_type; + } + + // This is crude + if (is_int($value)) { + return 'integer'; + } + // Catch floating point values which are not integer + if (is_numeric($value)) { + return 'text'; + } + + return 'text'; +} + +/** + * Utility function used by import_extender_plugin_hook() to process an ODDMetaData and add it to an entity. + * This function does not hit ->save() on the entity (this lets you construct in memory) + * + * @param ElggEntity The entity to add the data to. + * @param ODDMetaData $element The OpenDD element + * @return bool + */ +function oddmetadata_to_elggextender(ElggEntity $entity, ODDMetaData $element) { + // Get the type of extender (metadata, type, attribute etc) + $type = $element->getAttribute('type'); + $attr_name = $element->getAttribute('name'); + $attr_val = $element->getBody(); + + switch ($type) { + // Ignore volatile items + case 'volatile' : + break; + case 'annotation' : + $entity->annotate($attr_name, $attr_val); + break; + case 'metadata' : + $entity->setMetaData($attr_name, $attr_val, "", true); + break; + default : // Anything else assume attribute + $entity->set($attr_name, $attr_val); + } + + // Set time if appropriate + $attr_time = $element->getAttribute('published'); + if ($attr_time) { + $entity->set('time_updated', $attr_time); + } + + return true; +} + +/** + * Handler called by trigger_plugin_hook on the "import" event. + */ +function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params) { + $element = $params['element']; + + $tmp = NULL; + + if ($element instanceof ODDMetaData) { + // Recall entity + $entity_uuid = $element->getAttribute('entity_uuid'); + $entity = get_entity_from_uuid($entity_uuid); + if (!$entity) { + throw new ImportException(sprintf(elgg_echo('ImportException:GUIDNotFound'), $entity_uuid)); + } + + oddmetadata_to_elggextender($entity, $element); + + // Save + if (!$entity->save()) { + throw new ImportException(sprintf(elgg_echo('ImportException:ProblemUpdatingMeta'), $attr_name, $entity_uuid)); + } + + return true; + } +} + +/** + * Determines whether or not the specified user can edit the specified piece of extender + * + * @param int $extender_id The ID of the piece of extender + * @param string $type 'metadata' or 'annotation' + * @param int $user_guid The GUID of the user + * @return true|false + */ +function can_edit_extender($extender_id, $type, $user_guid = 0) { + if (!isloggedin()) { + return false; + } + + $user_guid = (int)$user_guid; + $user = get_entity($user_guid); + if (!$user) { + $user = get_loggedin_user(); + } + + $functionname = "get_{$type}"; + if (is_callable($functionname)) { + $extender = $functionname($extender_id); + } else { + return false; + } + + if (!is_a($extender,"ElggExtender")) { + return false; + } + + // If the owner is the specified user, great! They can edit. + if ($extender->getOwner() == $user->getGUID()) { + return true; + } + + // If the user can edit the entity this is attached to, great! They can edit. + if (can_edit_entity($extender->entity_guid,$user->getGUID())) { + return true; + } + + // Trigger plugin hooks + return trigger_plugin_hook('permissions_check',$type,array('entity' => $entity, 'user' => $user),false); +} + +/** + * Sets the URL handler for a particular extender type and name. + * It is recommended that you do not call this directly, instead use one of the wrapper functions in the + * subtype files. + * + * @param string $function_name The function to register + * @param string $extender_type Extender type + * @param string $extender_name The name of the extender + * @return true|false Depending on success + */ +function register_extender_url_handler($function_name, $extender_type = "all", $extender_name = "all") { + global $CONFIG; + + if (!is_callable($function_name)) { + return false; + } + + if (!isset($CONFIG->extender_url_handler)) { + $CONFIG->extender_url_handler = array(); + } + if (!isset($CONFIG->extender_url_handler[$extender_type])) { + $CONFIG->extender_url_handler[$extender_type] = array(); + } + $CONFIG->extender_url_handler[$extender_type][$extender_name] = $function_name; + + return true; +} + +/** + * Get the URL of a given elgg extender. + * Used by get_annotation_url and get_metadata_url. + * + * @param ElggExtender $extender + */ +function get_extender_url(ElggExtender $extender) { + global $CONFIG; + + $view = elgg_get_viewtype(); + + $guid = $extender->entity_guid; + $type = $extender->type; + + $url = ""; + + $function = ""; + if (isset($CONFIG->extender_url_handler[$type][$extender->name])) { + $function = $CONFIG->extender_url_handler[$type][$extender->name]; + } + + if (isset($CONFIG->extender_url_handler[$type]['all'])) { + $function = $CONFIG->extender_url_handler[$type]['all']; + } + + if (isset($CONFIG->extender_url_handler['all']['all'])) { + $function = $CONFIG->extender_url_handler['all']['all']; + } + + if (is_callable($function)) { + $url = $function($extender); + } + + if ($url == "") { + $nameid = $extender->id; + if ($type == 'volatile') { + $nameid== $extender->name; + } + $url = $CONFIG->wwwroot . "export/$view/$guid/$type/$nameid/"; + } + return $url; +} + +/** Register the hook */ +register_plugin_hook("import", "all", "import_extender_plugin_hook", 2); \ No newline at end of file diff --git a/engine/lib/filestore.php b/engine/lib/filestore.php index a7df5a8f0..852fbae8f 100644 --- a/engine/lib/filestore.php +++ b/engine/lib/filestore.php @@ -1,1346 +1,1319 @@ getParameters(). - */ - abstract public function setParameters(array $parameters); - - /** - * Get the contents of the whole file. - * - * @param mixed $file The file handle. - * @return mixed The file contents. - */ - abstract public function grabFile(ElggFile $file); - - /** - * Return whether a file physically exists or not. - * - * @param ElggFile $file - */ - abstract public function exists(ElggFile $file); - - } - + abstract public function write($f, $data); + /** - * @class ElggDiskFilestore - * This class uses disk storage to save data. - * @author Curverider Ltd + * Read data from a filestore. + * + * @param mixed $f The file handle + * @param int $length Length in bytes to read. + * @param int $offset The optional offset. + * @return mixed String of data or false on error. */ - class ElggDiskFilestore extends ElggFilestore - { - /** - * Directory root. - */ - private $dir_root; - - /** - * Default depth of file directory matrix - */ - private $matrix_depth = 5; - - /** - * Construct a disk filestore using the given directory root. - * - * @param string $directory_root Root directory, must end in "/" - */ - public function __construct($directory_root = "") - { - global $CONFIG; - - if ($directory_root) - $this->dir_root = $directory_root; - else - $this->dir_root = $CONFIG->dataroot; - } - - public function open(ElggFile $file, $mode) - { - $fullname = $this->getFilenameOnFilestore($file); - - // Split into path and name - $ls = strrpos($fullname,"/"); - if ($ls===false) $ls = 0; - - $path = substr($fullname, 0, $ls); - $name = substr($fullname, $ls); - - // Try and create the directory - try { $this->make_directory_root($path); } catch (Exception $e){} - - if (($mode!='write') && (!file_exists($fullname))) - return false; - - switch ($mode) - { - case "read" : $mode = "r+b"; break; - case "write" : $mode = "w+b"; break; - case "append" : $mode = "a+b"; break; - default: throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode)); - } - - return fopen($fullname, $mode); - - } - - public function write($f, $data) - { - return fwrite($f, $data); - } - - public function read($f, $length, $offset = 0) - { - if ($offset) - $this->seek($f, $offset); - - return fread($f, $length); - } - - public function close($f) - { - return fclose($f); + abstract public function read($f, $length, $offset = 0); + + /** + * Seek a given position within a file handle. + * + * @param mixed $f The file handle. + * @param int $position The position. + */ + abstract public function seek($f, $position); + + /** + * Return a whether the end of a file has been reached. + * + * @param mixed $f The file handle. + * @return boolean + */ + abstract public function eof($f); + + /** + * Return the current position in an open file. + * + * @param mixed $f The file handle. + * @return int + */ + abstract public function tell($f); + + /** + * Close a given file handle. + * + * @param mixed $f + */ + abstract public function close($f); + + /** + * Delete the file associated with a given file handle. + * + * @param ElggFile $file + */ + abstract public function delete(ElggFile $file); + + /** + * Return the size in bytes for a given file. + * + * @param ElggFile $file + */ + abstract public function getFileSize(ElggFile $file); + + /** + * Return the filename of a given file as stored on the filestore. + * + * @param ElggFile $file + */ + abstract public function getFilenameOnFilestore(ElggFile $file); + + /** + * Get the filestore's creation parameters as an associative array. + * Used for serialisation and for storing the creation details along side a file object. + * + * @return array + */ + abstract public function getParameters(); + + /** + * Set the parameters from the associative array produced by $this->getParameters(). + */ + abstract public function setParameters(array $parameters); + + /** + * Get the contents of the whole file. + * + * @param mixed $file The file handle. + * @return mixed The file contents. + */ + abstract public function grabFile(ElggFile $file); + + /** + * Return whether a file physically exists or not. + * + * @param ElggFile $file + */ + abstract public function exists(ElggFile $file); +} + +/** + * @class ElggDiskFilestore + * This class uses disk storage to save data. + * @author Curverider Ltd + */ +class ElggDiskFilestore extends ElggFilestore { + /** + * Directory root. + */ + private $dir_root; + + /** + * Default depth of file directory matrix + */ + private $matrix_depth = 5; + + /** + * Construct a disk filestore using the given directory root. + * + * @param string $directory_root Root directory, must end in "/" + */ + public function __construct($directory_root = "") { + global $CONFIG; + + if ($directory_root) { + $this->dir_root = $directory_root; + } else { + $this->dir_root = $CONFIG->dataroot; } - - public function delete(ElggFile $file) - { - $filename = $this->getFilenameOnFilestore($file); - if (file_exists($filename)) { - return unlink($filename); - } else { - return true; - } + } + + public function open(ElggFile $file, $mode) { + $fullname = $this->getFilenameOnFilestore($file); + + // Split into path and name + $ls = strrpos($fullname,"/"); + if ($ls===false) { + $ls = 0; } - - public function seek($f, $position) - { - return fseek($f, $position); + + $path = substr($fullname, 0, $ls); + $name = substr($fullname, $ls); + + // Try and create the directory + try { + $this->make_directory_root($path); + } catch (Exception $e) { + } - - public function tell($f) - { - return ftell($f); + + if (($mode!='write') && (!file_exists($fullname))) { + return false; } - - public function eof($f) - { - return feof($f); + + switch ($mode) { + case "read" : + $mode = "r+b"; + break; + case "write" : + $mode = "w+b"; + break; + case "append" : + $mode = "a+b"; + break; + default: + throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode)); } - - public function getFileSize(ElggFile $file) - { - return filesize($this->getFilenameOnFilestore($file)); + + return fopen($fullname, $mode); + + } + + public function write($f, $data) { + return fwrite($f, $data); + } + + public function read($f, $length, $offset = 0) { + if ($offset) { + $this->seek($f, $offset); } - - public function getFilenameOnFilestore(ElggFile $file) - { - $owner = $file->getOwnerEntity(); - if (!$owner) - $owner = get_loggedin_user(); - - if ((!$owner) || (!$owner->username)) throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:MissingOwner'), $file->getFilename(), $file->guid)); - - return $this->dir_root . $this->make_file_matrix($owner->username) . $file->getFilename(); + + return fread($f, $length); + } + + public function close($f) { + return fclose($f); + } + + public function delete(ElggFile $file) { + $filename = $this->getFilenameOnFilestore($file); + if (file_exists($filename)) { + return unlink($filename); + } else { + return true; } - - public function grabFile(ElggFile $file) { - - return file_get_contents($file->getFilenameOnFilestore()); - + } + + public function seek($f, $position) { + return fseek($f, $position); + } + + public function tell($f) { + return ftell($f); + } + + public function eof($f) { + return feof($f); + } + + public function getFileSize(ElggFile $file) { + return filesize($this->getFilenameOnFilestore($file)); + } + + public function getFilenameOnFilestore(ElggFile $file) { + $owner = $file->getOwnerEntity(); + if (!$owner) { + $owner = get_loggedin_user(); } - - public function exists(ElggFile $file) - { - return file_exists($this->getFilenameOnFilestore($file)); + + if ((!$owner) || (!$owner->username)) { + throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:MissingOwner'), $file->getFilename(), $file->guid)); } - - public function getSize($prefix,$container_guid) { - if ($container_guid && ($container=get_entity($container_guid)) && ($username = $container->username)) { - return get_dir_size($this->dir_root.$this->make_file_matrix($username).$prefix); - } else { - return false; - } + + return $this->dir_root . $this->make_file_matrix($owner->username) . $file->getFilename(); + } + + public function grabFile(ElggFile $file) { + return file_get_contents($file->getFilenameOnFilestore()); + } + + public function exists(ElggFile $file) { + return file_exists($this->getFilenameOnFilestore($file)); + } + + public function getSize($prefix,$container_guid) { + if ($container_guid && ($container=get_entity($container_guid)) && ($username = $container->username)) { + return get_dir_size($this->dir_root.$this->make_file_matrix($username).$prefix); + } else { + return false; } - - /** - * Make the directory root. - * - * @param string $dirroot - */ - protected function make_directory_root($dirroot) - { - if (!file_exists($dirroot)) - if (!@mkdir($dirroot, 0700, true)) + } + + /** + * Make the directory root. + * + * @param string $dirroot + */ + protected function make_directory_root($dirroot) { + if (!file_exists($dirroot)) { + if (!@mkdir($dirroot, 0700, true)) { throw new IOException(sprintf(elgg_echo('IOException:CouldNotMake'), $dirroot)); - - return true; - } - - /** - * Multibyte string tokeniser. - * - * Splits a string into an array. Will fail safely if mbstring is not installed (although this may still - * not handle . - * - * @param string $string String - * @param string $charset The charset, defaults to UTF8 - * @return array - */ - private function mb_str_split($string, $charset = 'UTF8') - { - if (is_callable('mb_substr')) - { - $length = mb_strlen($string); - $array = array(); - - while ($length) - { - $array[] = mb_substr($string, 0, 1, $charset); - $string = mb_substr($string, 1, $length, $charset); - - $length = mb_strlen($string); - } - - return $array; } - else - return str_split($string); - - return false; - } - - /** - * Construct the filename matrix. - * - * @param string $filename - */ - protected function make_file_matrix($filename) - { - $invalid_fs_chars = '*\'\\/"!$%^&*.%(){}[]#~?<>;|¬`@-+='; - - $matrix = ""; - - $name = $filename; - $filename = $this->mb_str_split($filename); - if (!$filename) return false; - - $len = count($filename); - if ($len>$this->matrix_depth) - $len = $this->matrix_depth; - - for ($n = 0; $n < $len; $n++) { - - // Prevent a matrix being formed with unsafe characters - $char = $filename[$n]; - if (strpos($invalid_fs_chars, $char)!==false) - $char = '_'; - - $matrix .= $char . "/"; - } - - return $matrix.$name."/"; } - - public function getParameters() - { - return array("dir_root" => $this->dir_root); - } - - public function setParameters(array $parameters) - { - if (isset($parameters['dir_root'])) - { - $this->dir_root = $parameters['dir_root']; - return true; + + return true; + } + + /** + * Multibyte string tokeniser. + * + * Splits a string into an array. Will fail safely if mbstring is not installed (although this may still + * not handle . + * + * @param string $string String + * @param string $charset The charset, defaults to UTF8 + * @return array + */ + private function mb_str_split($string, $charset = 'UTF8') { + if (is_callable('mb_substr')) { + $length = mb_strlen($string); + $array = array(); + + while ($length) { + $array[] = mb_substr($string, 0, 1, $charset); + $string = mb_substr($string, 1, $length, $charset); + + $length = mb_strlen($string); } - - return false; + + return $array; + } else { + return str_split($string); } + + return false; } - + /** - * @class ElggFile - * This class represents a physical file. - * - * Usage: - * Create a new ElggFile object and specify a filename, and optionally a FileStore (if one isn't specified - * then the default is assumed. - * - * Open the file using the appropriate mode, and you will be able to read and write to the file. - * - * Optionally, you can also call the file's save() method, this will turn the file into an entity in the - * system and permit you to do things like attach tags to the file etc. This is not done automatically since - * there are many occasions where you may want access to file data on datastores using the ElggFile interface - * but do not want to create an Entity reference to it in the system (temporary files for example). - * - * @author Curverider Ltd + * Construct the filename matrix. + * + * @param string $filename */ - class ElggFile extends ElggObject - { - /** Filestore */ - private $filestore; - - /** File handle used to identify this file in a filestore. Created by open. */ - private $handle; - - protected function initialise_attributes() - { - parent::initialise_attributes(); - - $this->attributes['subtype'] = "file"; + protected function make_file_matrix($filename) { + $invalid_fs_chars = '*\'\\/"!$%^&*.%(){}[]#~?<>;|¬`@-+='; + + $matrix = ""; + + $name = $filename; + $filename = $this->mb_str_split($filename); + if (!$filename) { + return false; } - - public function __construct($guid = null) - { - parent::__construct($guid); - - // Set default filestore - $this->filestore = $this->getFilestore(); + + $len = count($filename); + if ($len>$this->matrix_depth) { + $len = $this->matrix_depth; } - - /** - * Set the filename of this file. - * - * @param string $name The filename. - */ - public function setFilename($name) { $this->filename = $name; } - - /** - * Return the filename. - */ - public function getFilename() { return $this->filename; } - - /** - * Return the filename of this file as it is/will be stored on the filestore, which may be different - * to the filename. - */ - public function getFilenameOnFilestore() { return $this->filestore->getFilenameOnFilestore($this); } - - /* - * Return the size of the filestore associated with this file - * - */ - public function getFilestoreSize($prefix='',$container_guid=0) { - if (!$container_guid) { - $container_guid = $this->container_guid; + + for ($n = 0; $n < $len; $n++) { + // Prevent a matrix being formed with unsafe characters + $char = $filename[$n]; + if (strpos($invalid_fs_chars, $char)!==false) { + $char = '_'; } - $fs = $this->getFilestore(); - return $fs->getSize($prefix,$container_guid); - } - - /** - * Get the mime type of the file. - */ - public function getMimeType() - { - if ($this->mimetype) - return $this->mimetype; - - // TODO : Guess mimetype if not here - } - - /** - * Set the mime type of the file. - * - * @param $mimetype The mimetype - */ - public function setMimeType($mimetype) { return $this->mimetype = $mimetype; } - - /** - * Set the optional file description. - * - * @param string $description The description. - */ - public function setDescription($description) { $this->description = $description; } - - /** - * Open the file with the given mode - * - * @param string $mode Either read/write/append - */ - public function open($mode) - { - if (!$this->getFilename()) - throw new IOException(elgg_echo('IOException:MissingFileName')); - - // See if file has already been saved - // seek on datastore, parameters and name? - - // Sanity check - if ( - ($mode!="read") && - ($mode!="write") && - ($mode!="append") - ) - throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode)); - - // Get the filestore - $fs = $this->getFilestore(); - - // Ensure that we save the file details to object store - //$this->save(); - - // Open the file handle - $this->handle = $fs->open($this, $mode); - - return $this->handle; - } - - /** - * Write some data. - * - * @param string $data The data - */ - public function write($data) - { - $fs = $this->getFilestore(); - - return $fs->write($this->handle, $data); - } - - /** - * Read some data. - * - * @param int $length Amount to read. - * @param int $offset The offset to start from. - */ - public function read($length, $offset = 0) - { - $fs = $this->getFilestore(); - - return $fs->read($this->handle, $length, $offset); - } - - /** - * Gets the full contents of this file. - * - * @return mixed The file contents. - */ - public function grabFile() { - - $fs = $this->getFilestore(); - return $fs->grabFile($this); - + + $matrix .= $char . "/"; } - - /** - * Close the file and commit changes - */ - public function close() - { - $fs = $this->getFilestore(); - - if ($fs->close($this->handle)) - { - $this->handle = NULL; - - return true; - } - - return false; + + return $matrix.$name."/"; + } + + public function getParameters() { + return array("dir_root" => $this->dir_root); + } + + public function setParameters(array $parameters) { + if (isset($parameters['dir_root'])) { + $this->dir_root = $parameters['dir_root']; + return true; } - - /** - * Delete this file. - */ - public function delete() - { - $fs = $this->getFilestore(); - if ($fs->delete($this)) { - return parent::delete(); - } + + return false; + } +} + +/** + * @class ElggFile + * This class represents a physical file. + * + * Usage: + * Create a new ElggFile object and specify a filename, and optionally a FileStore (if one isn't specified + * then the default is assumed. + * + * Open the file using the appropriate mode, and you will be able to read and write to the file. + * + * Optionally, you can also call the file's save() method, this will turn the file into an entity in the + * system and permit you to do things like attach tags to the file etc. This is not done automatically since + * there are many occasions where you may want access to file data on datastores using the ElggFile interface + * but do not want to create an Entity reference to it in the system (temporary files for example). + * + * @author Curverider Ltd + */ +class ElggFile extends ElggObject { + /** Filestore */ + private $filestore; + + /** File handle used to identify this file in a filestore. Created by open. */ + private $handle; + + protected function initialise_attributes() { + parent::initialise_attributes(); + + $this->attributes['subtype'] = "file"; + } + + public function __construct($guid = null) { + parent::__construct($guid); + + // Set default filestore + $this->filestore = $this->getFilestore(); + } + + /** + * Set the filename of this file. + * + * @param string $name The filename. + */ + public function setFilename($name) { + $this->filename = $name; + } + + /** + * Return the filename. + */ + public function getFilename() { + return $this->filename; + } + + /** + * Return the filename of this file as it is/will be stored on the filestore, which may be different + * to the filename. + */ + public function getFilenameOnFilestore() { + return $this->filestore->getFilenameOnFilestore($this); + } + + /* + * Return the size of the filestore associated with this file + * + */ + public function getFilestoreSize($prefix='',$container_guid=0) { + if (!$container_guid) { + $container_guid = $this->container_guid; } - - /** - * Seek a position in the file. - * - * @param int $position - */ - public function seek($position) - { - $fs = $this->getFilestore(); - - return $fs->seek($this->handle, $position); + $fs = $this->getFilestore(); + return $fs->getSize($prefix,$container_guid); + } + + /** + * Get the mime type of the file. + */ + public function getMimeType() { + if ($this->mimetype) { + return $this->mimetype; } - - /** - * Return the current position of the file. - * - * @return int The file position - */ - public function tell() - { - $fs = $this->getFilestore(); - - return $fs->tell($this->handle); + + // TODO : Guess mimetype if not here + } + + /** + * Set the mime type of the file. + * + * @param $mimetype The mimetype + */ + public function setMimeType($mimetype) { + return $this->mimetype = $mimetype; + } + + /** + * Set the optional file description. + * + * @param string $description The description. + */ + public function setDescription($description) { + $this->description = $description; + } + + /** + * Open the file with the given mode + * + * @param string $mode Either read/write/append + */ + public function open($mode) { + if (!$this->getFilename()) { + throw new IOException(elgg_echo('IOException:MissingFileName')); } - - /** - * Return the size of the file in bytes. - */ - public function size() - { - return $this->filestore->getFileSize($this); + + // See if file has already been saved + // seek on datastore, parameters and name? + + // Sanity check + if ( + ($mode!="read") && + ($mode!="write") && + ($mode!="append") + ) { + throw new InvalidParameterException(sprintf(elgg_echo('InvalidParameterException:UnrecognisedFileMode'), $mode)); } - - /** - * Return a boolean value whether the file handle is at the end of the file - */ - public function eof() - { - $fs = $this->getFilestore(); - - return $fs->eof($this->handle); + + // Get the filestore + $fs = $this->getFilestore(); + + // Ensure that we save the file details to object store + //$this->save(); + + // Open the file handle + $this->handle = $fs->open($this, $mode); + + return $this->handle; + } + + /** + * Write some data. + * + * @param string $data The data + */ + public function write($data) { + $fs = $this->getFilestore(); + + return $fs->write($this->handle, $data); + } + + /** + * Read some data. + * + * @param int $length Amount to read. + * @param int $offset The offset to start from. + */ + public function read($length, $offset = 0) { + $fs = $this->getFilestore(); + + return $fs->read($this->handle, $length, $offset); + } + + /** + * Gets the full contents of this file. + * + * @return mixed The file contents. + */ + public function grabFile() { + $fs = $this->getFilestore(); + return $fs->grabFile($this); + } + + /** + * Close the file and commit changes + */ + public function close() { + $fs = $this->getFilestore(); + + if ($fs->close($this->handle)) { + $this->handle = NULL; + + return true; } - - public function exists() - { - $fs = $this->getFilestore(); - - return $fs->exists($this); + + return false; + } + + /** + * Delete this file. + */ + public function delete() { + $fs = $this->getFilestore(); + if ($fs->delete($this)) { + return parent::delete(); } - - /** - * Set a filestore. - * - * @param ElggFilestore $filestore The file store. - */ - public function setFilestore(ElggFilestore $filestore) - { - $this->filestore = $filestore; + } + + /** + * Seek a position in the file. + * + * @param int $position + */ + public function seek($position) { + $fs = $this->getFilestore(); + + return $fs->seek($this->handle, $position); + } + + /** + * Return the current position of the file. + * + * @return int The file position + */ + public function tell() { + $fs = $this->getFilestore(); + + return $fs->tell($this->handle); + } + + /** + * Return the size of the file in bytes. + */ + public function size() { + return $this->filestore->getFileSize($this); + } + + /** + * Return a boolean value whether the file handle is at the end of the file + */ + public function eof() { + $fs = $this->getFilestore(); + + return $fs->eof($this->handle); + } + + public function exists() { + $fs = $this->getFilestore(); + + return $fs->exists($this); + } + + /** + * Set a filestore. + * + * @param ElggFilestore $filestore The file store. + */ + public function setFilestore(ElggFilestore $filestore) { + $this->filestore = $filestore; + } + + /** + * Return a filestore suitable for saving this file. + * This filestore is either a pre-registered filestore, a filestore loaded from metatags saved + * along side this file, or the system default. + */ + protected function getFilestore() { + // Short circuit if already set. + if ($this->filestore) { + return $this->filestore; } - - /** - * Return a filestore suitable for saving this file. - * This filestore is either a pre-registered filestore, a filestore loaded from metatags saved - * along side this file, or the system default. - */ - protected function getFilestore() - { - // Short circuit if already set. - if ($this->filestore) - return $this->filestore; - - - // If filestore meta set then retrieve filestore TODO: Better way of doing this? - $metas = get_metadata_for_entity($this->guid); - $parameters = array(); - if (is_array($metas)) - foreach ($metas as $meta) - { - if (strpos($meta->name, "filestore::")!==false) - { + + // If filestore meta set then retrieve filestore TODO: Better way of doing this? + $metas = get_metadata_for_entity($this->guid); + $parameters = array(); + if (is_array($metas)) { + foreach ($metas as $meta) { + if (strpos($meta->name, "filestore::")!==false) { // Filestore parameter tag $comp = explode("::", $meta->name); - $name = $comp[1]; - + $name = $comp[1]; + $parameters[$name] = $meta->value; } } - - // If parameters loaded then create new filestore - if (count($parameters)!=0) - { - // Create new filestore object - if ((!isset($parameters['filestore'])) || (!class_exists($parameters['filestore']))) - throw new ClassNotFoundException(elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile')); - - $this->filestore = new $parameters['filestore'](); - - // Set parameters - $this->filestore->setParameters($parameters); + } + + // If parameters loaded then create new filestore + if (count($parameters)!=0) { + // Create new filestore object + if ((!isset($parameters['filestore'])) || (!class_exists($parameters['filestore']))) { + throw new ClassNotFoundException(elgg_echo('ClassNotFoundException:NotFoundNotSavedWithFile')); } - - // if still nothing then set filestore to default - if (!$this->filestore) - $this->filestore = get_default_filestore(); + $this->filestore = new $parameters['filestore'](); - return $this->filestore; + // Set parameters + $this->filestore->setParameters($parameters); } - - public function save() - { - if (!parent::save()) - return false; - - // Save datastore metadata - $params = $this->filestore->getParameters(); - foreach ($params as $k => $v) - $this->setMetaData("filestore::$k", $v); - - // Now make a note of the filestore class - $this->setMetaData("filestore::filestore", get_class($this->filestore)); - - return true; + + + // if still nothing then set filestore to default + if (!$this->filestore) { + $this->filestore = get_default_filestore(); } - + + return $this->filestore; } - - /** - * Get the size of the specified directory. - * - * @param string $dir The full path of the directory - * @return int The size of the directory. - */ - function get_dir_size($dir,$totalsize = 0){ - $handle = @opendir($dir); - while ($file = @readdir ($handle)){ - if (eregi("^\.{1,2}$",$file)) - continue; - if(is_dir($dir.$file)){ - $totalsize = get_dir_size($dir.$file."/",$totalsize); - } else{ - $totalsize += filesize($dir.$file); - } - } - @closedir($handle); - - return($totalsize); - } - - /** - * Get the contents of an uploaded file. - * (Returns false if there was an issue.) - * - * @param string $input_name The name of the file input field on the submission form - * @return mixed|false The contents of the file, or false on failure. - */ - function get_uploaded_file($input_name) { - - // If the file exists ... - if (isset($_FILES[$input_name]) && $_FILES[$input_name]['error'] == 0) { - return file_get_contents($_FILES[$input_name]['tmp_name']); + + public function save() { + if (!parent::save()) { + return false; } - return false; - + + // Save datastore metadata + $params = $this->filestore->getParameters(); + foreach ($params as $k => $v) { + $this->setMetaData("filestore::$k", $v); + } + + // Now make a note of the filestore class + $this->setMetaData("filestore::filestore", get_class($this->filestore)); + + return true; } - - /** - * Gets the jpeg contents of the resized version of an uploaded image - * (Returns false if the uploaded file was not an image) - * - * @param string $input_name The name of the file input field on the submission form - * @param int $maxwidth The maximum width of the resized image - * @param int $maxheight The maximum height of the resized image - * @param true|false $square If set to true, will take the smallest of maxwidth and maxheight and use it to set the dimensions on all size; the image will be cropped. - * @return false|mixed The contents of the resized image, or false on failure - */ - function get_resized_image_from_uploaded_file($input_name, $maxwidth, $maxheight, $square = false) { - // If our file exists ... - if (isset($_FILES[$input_name]) && $_FILES[$input_name]['error'] == 0) { - - return get_resized_image_from_existing_file($_FILES[$input_name]['tmp_name'], $maxwidth, $maxheight, $square); - +} + +/** + * Get the size of the specified directory. + * + * @param string $dir The full path of the directory + * @return int The size of the directory. + */ +function get_dir_size($dir, $totalsize = 0){ + $handle = @opendir($dir); + while ($file = @readdir ($handle)){ + if (eregi("^\.{1,2}$", $file)) { + continue; + } + if(is_dir($dir . $file)) { + $totalsize = get_dir_size($dir . $file . "/", $totalsize); + } else{ + $totalsize += filesize($dir . $file); } - - return false; } - - /** - * Gets the jpeg contents of the resized version of an already uploaded image - * (Returns false if the uploaded file was not an image) - * - * @param string $input_name The name of the file input field on the submission form - * @param int $maxwidth The maximum width of the resized image - * @param int $maxheight The maximum height of the resized image - * @param true|false $square If set to true, will take the smallest of maxwidth and maxheight and use it to set the dimensions on all size; the image will be cropped. - * @return false|mixed The contents of the resized image, or false on failure - */ - function get_resized_image_from_existing_file($input_name, $maxwidth, $maxheight, $square = false, $x1 = 0, $y1 = 0, $x2 = 0, $y2 = 0) { - - // Get the size information from the image - if ($imgsizearray = getimagesize($input_name)) { - - // Get width and height - $width = $imgsizearray[0]; - $height = $imgsizearray[1]; + @closedir($handle); + + return($totalsize); +} + +/** + * Get the contents of an uploaded file. + * (Returns false if there was an issue.) + * + * @param string $input_name The name of the file input field on the submission form + * @return mixed|false The contents of the file, or false on failure. + */ +function get_uploaded_file($input_name) { + // If the file exists ... + if (isset($_FILES[$input_name]) && $_FILES[$input_name]['error'] == 0) { + return file_get_contents($_FILES[$input_name]['tmp_name']); + } + return false; +} + +/** + * Gets the jpeg contents of the resized version of an uploaded image + * (Returns false if the uploaded file was not an image) + * + * @param string $input_name The name of the file input field on the submission form + * @param int $maxwidth The maximum width of the resized image + * @param int $maxheight The maximum height of the resized image + * @param true|false $square If set to true, will take the smallest of maxwidth and maxheight and use it to set the dimensions on all size; the image will be cropped. + * @return false|mixed The contents of the resized image, or false on failure + */ +function get_resized_image_from_uploaded_file($input_name, $maxwidth, $maxheight, $square = false) { + // If our file exists ... + if (isset($_FILES[$input_name]) && $_FILES[$input_name]['error'] == 0) { + return get_resized_image_from_existing_file($_FILES[$input_name]['tmp_name'], $maxwidth, $maxheight, $square); + } + + return false; +} + +/** + * Gets the jpeg contents of the resized version of an already uploaded image + * (Returns false if the uploaded file was not an image) + * + * @param string $input_name The name of the file input field on the submission form + * @param int $maxwidth The maximum width of the resized image + * @param int $maxheight The maximum height of the resized image + * @param true|false $square If set to true, will take the smallest of maxwidth and maxheight and use it to set the dimensions on all size; the image will be cropped. + * @return false|mixed The contents of the resized image, or false on failure + */ +function get_resized_image_from_existing_file($input_name, $maxwidth, $maxheight, $square = false, $x1 = 0, $y1 = 0, $x2 = 0, $y2 = 0) { + // Get the size information from the image + if ($imgsizearray = getimagesize($input_name)) { + // Get width and height + $width = $imgsizearray[0]; + $height = $imgsizearray[1]; + $newwidth = $width; + $newheight = $height; + + // Square the image dimensions if we're wanting a square image + if ($square) { + if ($width < $height) { + $height = $width; + } else { + $width = $height; + } + $newwidth = $width; $newheight = $height; - - // Square the image dimensions if we're wanting a square image - if ($square) { - if ($width < $height) { - $height = $width; + } + + if ($width > $maxwidth) { + $newheight = floor($height * ($maxwidth / $width)); + $newwidth = $maxwidth; + } + + if ($newheight > $maxheight) { + $newwidth = floor($newwidth * ($maxheight / $newheight)); + $newheight = $maxheight; + } + + $accepted_formats = array( + 'image/jpeg' => 'jpeg', + 'image/png' => 'png', + 'image/gif' => 'gif' + ); + + // If it's a file we can manipulate ... + if (array_key_exists($imgsizearray['mime'],$accepted_formats)) { + $function = "imagecreatefrom" . $accepted_formats[$imgsizearray['mime']]; + $newimage = imagecreatetruecolor($newwidth,$newheight); + + if (is_callable($function) && $oldimage = $function($input_name)) { + // Crop the image if we need a square + if ($square) { + if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 ==0) { + $widthoffset = floor(($imgsizearray[0] - $width) / 2); + $heightoffset = floor(($imgsizearray[1] - $height) / 2); + } else { + $widthoffset = $x1; + $heightoffset = $y1; + $width = ($x2 - $x1); + $height = $width; + } } else { - $width = $height; - } - - $newwidth = $width; - $newheight = $height; - - } - - if ($width > $maxwidth) { - $newheight = floor($height * ($maxwidth / $width)); - $newwidth = $maxwidth; - } - if ($newheight > $maxheight) { - $newwidth = floor($newwidth * ($maxheight / $newheight)); - $newheight = $maxheight; - } - - $accepted_formats = array( - 'image/jpeg' => 'jpeg', - 'image/png' => 'png', - 'image/gif' => 'gif' - ); - - // If it's a file we can manipulate ... - if (array_key_exists($imgsizearray['mime'],$accepted_formats)) { - - $function = "imagecreatefrom" . $accepted_formats[$imgsizearray['mime']]; - $newimage = imagecreatetruecolor($newwidth,$newheight); - - if (is_callable($function) && $oldimage = $function($input_name)) { - - // Crop the image if we need a square - if ($square) { - if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 ==0) { - $widthoffset = floor(($imgsizearray[0] - $width) / 2); - $heightoffset = floor(($imgsizearray[1] - $height) / 2); - } else { - $widthoffset = $x1; - $heightoffset = $y1; - $width = ($x2 - $x1); - $height = $width; - } + if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 ==0) { + $widthoffset = 0; + $heightoffset = 0; } else { - if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 ==0) { - $widthoffset = 0; - $heightoffset = 0; - } else { - $widthoffset = $x1; - $heightoffset = $y1; - $width = ($x2 - $x1); - $height = ($y2 - $y1); - } - }//else { - // Resize and return the image contents! - if ($square) { - $newheight = $maxheight; - $newwidth = $maxwidth; - } - imagecopyresampled($newimage, $oldimage, 0,0,$widthoffset,$heightoffset,$newwidth,$newheight,$width,$height); - //} - - // imagecopyresized($newimage, $oldimage, 0,0,0,0,$newwidth,$newheight,$width,$height); - ob_start(); - imagejpeg($newimage, null, 90); - $jpeg = ob_get_clean(); - return $jpeg; - - } - + $widthoffset = $x1; + $heightoffset = $y1; + $width = ($x2 - $x1); + $height = ($y2 - $y1); + } + }//else { + // Resize and return the image contents! + if ($square) { + $newheight = $maxheight; + $newwidth = $maxwidth; + } + imagecopyresampled($newimage, $oldimage, 0,0,$widthoffset,$heightoffset,$newwidth,$newheight,$width,$height); + //} + + // imagecopyresized($newimage, $oldimage, 0,0,0,0,$newwidth,$newheight,$width,$height); + ob_start(); + imagejpeg($newimage, null, 90); + $jpeg = ob_get_clean(); + return $jpeg; } - } - - return false; } - - - // putting these here for now - - function file_delete($guid) { - if ($file = get_entity($guid)) { - - if ($file->canEdit()) { - - $container = get_entity($file->container_guid); - - $thumbnail = $file->thumbnail; - $smallthumb = $file->smallthumb; - $largethumb = $file->largethumb; - if ($thumbnail) { - - $delfile = new ElggFile(); - $delfile->owner_guid = $file->owner_guid; - $delfile->setFilename($thumbnail); - $delfile->delete(); - - } - if ($smallthumb) { - - $delfile = new ElggFile(); - $delfile->owner_guid = $file->owner_guid; - $delfile->setFilename($smallthumb); - $delfile->delete(); - - } - if ($largethumb) { - - $delfile = new ElggFile(); - $delfile->owner_guid = $file->owner_guid; - $delfile->setFilename($largethumb); - $delfile->delete(); - - } - - return $file->delete(); + + return false; +} + + +// putting these here for now + +function file_delete($guid) { + if ($file = get_entity($guid)) { + if ($file->canEdit()) { + $container = get_entity($file->container_guid); + + $thumbnail = $file->thumbnail; + $smallthumb = $file->smallthumb; + $largethumb = $file->largethumb; + if ($thumbnail) { + $delfile = new ElggFile(); + $delfile->owner_guid = $file->owner_guid; + $delfile->setFilename($thumbnail); + $delfile->delete(); + } + if ($smallthumb) { + $delfile = new ElggFile(); + $delfile->owner_guid = $file->owner_guid; + $delfile->setFilename($smallthumb); + $delfile->delete(); } + if ($largethumb) { + $delfile = new ElggFile(); + $delfile->owner_guid = $file->owner_guid; + $delfile->setFilename($largethumb); + $delfile->delete(); + } + + return $file->delete(); } - - return false; } - - /** - * Returns an overall file type from the mimetype - * - * @param string $mimetype The MIME type - * @return string The overall type - */ - function file_get_general_file_type($mimetype) { - - switch($mimetype) { - - case "application/msword": - return "document"; - break; - case "application/pdf": - return "document"; - break; - - } - - if (substr_count($mimetype,'text/')) + + return false; +} + +/** + * Returns an overall file type from the mimetype + * + * @param string $mimetype The MIME type + * @return string The overall type + */ +function file_get_general_file_type($mimetype) { + switch($mimetype) { + + case "application/msword": return "document"; - - if (substr_count($mimetype,'audio/')) - return "audio"; - - if (substr_count($mimetype,'image/')) - return "image"; - - if (substr_count($mimetype,'video/')) - return "video"; - - if (substr_count($mimetype,'opendocument')) - return "document"; - - return "general"; - - } - - function file_handle_upload($prefix,$subtype,$plugin) { - $desc = get_input("description"); - $tags = get_input("tags"); - $tags = explode(",", $tags); - $folder = get_input("folder_text"); - if (!$folder) { - $folder = get_input("folder_select"); + break; + case "application/pdf": + return "document"; + break; + } + + if (substr_count($mimetype,'text/')) { + return "document"; + } + + if (substr_count($mimetype,'audio/')) { + return "audio"; + } + + if (substr_count($mimetype,'image/')) { + return "image"; + } + + if (substr_count($mimetype,'video/')) { + return "video"; + } + + if (substr_count($mimetype,'opendocument')) { + return "document"; + } + + return "general"; +} + +function file_handle_upload($prefix,$subtype,$plugin) { + $desc = get_input("description"); + $tags = get_input("tags"); + $tags = explode(",", $tags); + $folder = get_input("folder_text"); + if (!$folder) { + $folder = get_input("folder_select"); + } + $access_id = (int) get_input("access_id"); + $container_guid = (int) get_input('container_guid', 0); + if (!$container_guid) { + $container_guid == get_loggedin_userid(); + } + + // Extract file from, save to default filestore (for now) + + // see if a plugin has set a quota for this user + $file_quota = trigger_plugin_hook("$plugin:quotacheck",'user',array('container_guid'=>$container_guid)); + if (!$file_quota) { + // no, see if there is a generic quota set + $file_quota = get_plugin_setting('quota', $plugin); + } + if ($file_quota) { + // convert to megabytes + $file_quota = $file_quota*1000*1024; + } + + // handle uploaded files + $number_of_files = get_input('number_of_files',0); + $quota_exceeded = false; + $bad_mime_type = false; + + for ($i = 0; $i < $number_of_files; $i++) { + $title = get_input("title_".$i); + $uploaded = $_FILES["upload_".$i]; + if (!$uploaded || !$uploaded['name']) { + // no such file, so skip it + continue; } - $access_id = (int) get_input("access_id"); - $container_guid = (int) get_input('container_guid', 0); - if (!$container_guid) - $container_guid == get_loggedin_userid(); - - // Extract file from, save to default filestore (for now) - - // see if a plugin has set a quota for this user - $file_quota = trigger_plugin_hook("$plugin:quotacheck",'user',array('container_guid'=>$container_guid)); - if (!$file_quota) { - // no, see if there is a generic quota set - $file_quota = get_plugin_setting('quota', $plugin); + if ($plugin == "photo") { + // do a mime type test + if (in_array($uploaded['type'],array('image/jpeg','image/gif','image/png','image/jpg','image/jpe','image/pjpeg','image/x-png'))) { + $file = new PhotoPluginFile(); + } else { + $bad_mime_type = true; + break; + } + } else { + $file = new FilePluginFile(); } + $dir_size = $file->getFilestoreSize($prefix,$container_guid); + $filestorename = strtolower(time().$uploaded['name']); + $file->setFilename($prefix.$filestorename); + $file->setMimeType($uploaded['type']); + + $file->originalfilename = $uploaded['name']; + + $file->subtype = $subtype; + + $file->access_id = $access_id; + + $uf = get_uploaded_file('upload_'.$i); + if ($file_quota) { - // convert to megabytes - $file_quota = $file_quota*1000*1024; - } - - // handle uploaded files - $number_of_files = get_input('number_of_files',0); - $quota_exceeded = false; - $bad_mime_type = false; - - for ($i = 0; $i < $number_of_files; $i++) { - - $title = get_input("title_".$i); - $uploaded = $_FILES["upload_".$i]; - if (!$uploaded || !$uploaded['name']) { - // no such file, so skip it - continue; + $file_size = strlen($uf); + if (($dir_size + $file_size) > $file_quota) { + $quota_exceeded = true; } - if ($plugin == "photo") { - // do a mime type test - if (in_array($uploaded['type'],array('image/jpeg','image/gif','image/png','image/jpg','image/jpe','image/pjpeg','image/x-png'))) { - $file = new PhotoPluginFile(); - } else { - $bad_mime_type = true; - break; - } - - } else { - $file = new FilePluginFile(); - } - $dir_size = $file->getFilestoreSize($prefix,$container_guid); - $filestorename = strtolower(time().$uploaded['name']); - $file->setFilename($prefix.$filestorename); - $file->setMimeType($uploaded['type']); - - $file->originalfilename = $uploaded['name']; - - $file->subtype = $subtype; - - $file->access_id = $access_id; - - $uf = get_uploaded_file('upload_'.$i); - - if ($file_quota) { - $file_size = strlen($uf); - if (($dir_size + $file_size) > $file_quota) { - $quota_exceeded = true; - } + } + + if (!$quota_exceeded) { + // all clear, so try to save the data + + $file->open("write"); + $file->write($uf); + $file->close(); + + $file->title = $title; + $file->description = $desc; + if ($container_guid) { + $file->container_guid = $container_guid; } - - if (!$quota_exceeded) { - // all clear, so try to save the data - - $file->open("write"); - $file->write($uf); - $file->close(); - - $file->title = $title; - $file->description = $desc; - if ($container_guid) - $file->container_guid = $container_guid; - - // Save tags - $file->tags = $tags; - - $file->simpletype = file_get_general_file_type($uploaded['type']); - $file->folder = $folder; - - $result = $file->save(); - - if ($result) - { - - // Generate thumbnail (if image) - if (substr_count($file->getMimeType(),'image/')) - { - $thumbnail = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),60,60, true); - $thumbsmall = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),153,153, true); - $thumblarge = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),600,600, false); - if ($thumbnail) { - $thumb = new ElggFile(); - $thumb->setMimeType($uploaded['type']); - - $thumb->setFilename($prefix."thumb".$filestorename); - $thumb->open("write"); - $thumb->write($thumbnail); - $thumb->close(); - - $file->thumbnail = $prefix."thumb".$filestorename; - - $thumb->setFilename($prefix."smallthumb".$filestorename); - $thumb->open("write"); - $thumb->write($thumbsmall); - $thumb->close(); - $file->smallthumb = $prefix."smallthumb".$filestorename; - - $thumb->setFilename($prefix."largethumb".$filestorename); - $thumb->open("write"); - $thumb->write($thumblarge); - $thumb->close(); - $file->largethumb = $prefix."largethumb".$filestorename; - - } + + // Save tags + $file->tags = $tags; + + $file->simpletype = file_get_general_file_type($uploaded['type']); + $file->folder = $folder; + + $result = $file->save(); + + if ($result) { + + // Generate thumbnail (if image) + if (substr_count($file->getMimeType(),'image/')) { + $thumbnail = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),60,60, true); + $thumbsmall = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),153,153, true); + $thumblarge = get_resized_image_from_existing_file($file->getFilenameOnFilestore(),600,600, false); + if ($thumbnail) { + $thumb = new ElggFile(); + $thumb->setMimeType($uploaded['type']); + + $thumb->setFilename($prefix."thumb".$filestorename); + $thumb->open("write"); + $thumb->write($thumbnail); + $thumb->close(); + + $file->thumbnail = $prefix."thumb".$filestorename; + + $thumb->setFilename($prefix."smallthumb".$filestorename); + $thumb->open("write"); + $thumb->write($thumbsmall); + $thumb->close(); + $file->smallthumb = $prefix."smallthumb".$filestorename; + + $thumb->setFilename($prefix."largethumb".$filestorename); + $thumb->open("write"); + $thumb->write($thumblarge); + $thumb->close(); + $file->largethumb = $prefix."largethumb".$filestorename; } - - // add to this user's file folders - file_add_to_folders($folder,$container_guid,$plugin); - - add_to_river("river/object/$plugin/create",'create',$_SESSION['user']->guid,$file->guid); - } else { - break; } + + // add to this user's file folders + file_add_to_folders($folder,$container_guid,$plugin); + + add_to_river("river/object/$plugin/create",'create',$_SESSION['user']->guid,$file->guid); } else { break; } + } else { + break; } - - if ($quota_exceeded) { - echo elgg_echo("$plugin:quotaexceeded"); - } else if ($bad_mime_type) { - echo elgg_echo("$plugin:badmimetype"); - } else if ($result) { - if ($number_of_files > 1) { - echo elgg_echo("$plugin:saved_multi"); - } else { - echo elgg_echo("$plugin:saved"); - } - } else { - if ($number_of_files > 1) { - echo elgg_echo("$plugin:uploadfailed_multi"); - } else { - echo elgg_echo("$plugin:uploadfailed"); - } + } + + if ($quota_exceeded) { + echo elgg_echo("$plugin:quotaexceeded"); + } else if ($bad_mime_type) { + echo elgg_echo("$plugin:badmimetype"); + } else if ($result) { + if ($number_of_files > 1) { + echo elgg_echo("$plugin:saved_multi"); + } else { + echo elgg_echo("$plugin:saved"); + } + } else { + if ($number_of_files > 1) { + echo elgg_echo("$plugin:uploadfailed_multi"); + } else { + echo elgg_echo("$plugin:uploadfailed"); } } - - function file_add_to_folders($folder,$container_guid,$plugin) { - if ($container_guid && ($container = get_entity($container_guid))) { - $folder_field_name = 'elgg_'.$plugin.'_folders'; - $folders = $container->$folder_field_name; - if ($folders) { - if (is_array($folders)) { - if (!in_array($folder,$folders)) { - $folders[] = $folder; - $container->$folder_field_name = $folders; - } - } else { - if ($folders != $folder) { - $container->$folder_field_name = array($folders,$folder); - } +} + +function file_add_to_folders($folder,$container_guid,$plugin) { + if ($container_guid && ($container = get_entity($container_guid))) { + $folder_field_name = 'elgg_'.$plugin.'_folders'; + $folders = $container->$folder_field_name; + if ($folders) { + if (is_array($folders)) { + if (!in_array($folder,$folders)) { + $folders[] = $folder; + $container->$folder_field_name = $folders; + } + } else { + if ($folders != $folder) { + $container->$folder_field_name = array($folders,$folder); } - } else { - $container->$folder_field_name = $folder; } + } else { + $container->$folder_field_name = $folder; } } - - function file_handle_save($forward,$plugin) { - // Get variables - $title = get_input("title"); - $desc = get_input("description"); - $tags = get_input("tags"); - $folder = get_input("folder_text"); - if (!$folder) { - $folder = get_input("folder_select"); +} + +function file_handle_save($forward,$plugin) { + // Get variables + $title = get_input("title"); + $desc = get_input("description"); + $tags = get_input("tags"); + $folder = get_input("folder_text"); + if (!$folder) { + $folder = get_input("folder_select"); + } + $access_id = (int) get_input("access_id"); + + $guid = (int) get_input('file_guid'); + + if (!$file = get_entity($guid)) { + register_error(elgg_echo("$plugin:uploadfailed")); + forward($forward . $_SESSION['user']->username); + exit; + } + + $result = false; + + $container_guid = $file->container_guid; + $container = get_entity($container_guid); + + if ($file->canEdit()) { + $file->access_id = $access_id; + $file->title = $title; + $file->description = $desc; + $file->folder = $folder; + // add to this user's file folders + file_add_to_folders($folder,$container_guid,$plugin); + + // Save tags + $tags = explode(",", $tags); + $file->tags = $tags; + + $result = $file->save(); + } + + if ($result) { + system_message(elgg_echo("$plugin:saved")); + } else { + register_error(elgg_echo("$plugin:uploadfailed")); + } + forward($forward . $container->username); +} + +/** + * Manage a file download. + * + * @param unknown_type $plugin + * @param unknown_type $file_guid If not specified then file_guid will be found in input. + */ +function file_manage_download($plugin, $file_guid = "") { + // Get the guid + $file_guid = (int)$file_guid; + + if (!$file_guid) { + $file_guid = (int)get_input("file_guid"); + } + + // Get the file + $file = get_entity($file_guid); + + if ($file) { + $mime = $file->getMimeType(); + if (!$mime) { + $mime = "application/octet-stream"; } - $access_id = (int) get_input("access_id"); - - $guid = (int) get_input('file_guid'); - - if (!$file = get_entity($guid)) { - register_error(elgg_echo("$plugin:uploadfailed")); - forward($forward . $_SESSION['user']->username); - exit; + + $filename = $file->originalfilename; + + header("Content-type: $mime"); + if (strpos($mime, "image/")!==false) { + header("Content-Disposition: inline; filename=\"$filename\""); + } else { + header("Content-Disposition: attachment; filename=\"$filename\""); } - - $result = false; - - $container_guid = $file->container_guid; - $container = get_entity($container_guid); - - if ($file->canEdit()) { - - $file->access_id = $access_id; - $file->title = $title; - $file->description = $desc; - $file->folder = $folder; - // add to this user's file folders - file_add_to_folders($folder,$container_guid,$plugin); - - // Save tags - $tags = explode(",", $tags); - $file->tags = $tags; - - $result = $file->save(); + + echo $file->grabFile(); + exit; + } else { + register_error(elgg_echo("$plugin:downloadfailed")); + } +} + +/** + * Manage the download of a file icon. + * + * @param unknown_type $plugin + * @param unknown_type $file_guid The guid, if not specified this is obtained from the input. + */ +function file_manage_icon_download($plugin, $file_guid = "") { + // Get the guid + $file_guid = (int)$file_guid; + + if (!$file_guid) { + $file_guid = (int)get_input("file_guid"); + } + + // Get the file + $file = get_entity($file_guid); + + if ($file) { + $mime = $file->getMimeType(); + if (!$mime) { + $mime = "application/octet-stream"; } - - if ($result) - system_message(elgg_echo("$plugin:saved")); - else - register_error(elgg_echo("$plugin:uploadfailed")); - - forward($forward . $container->username); - } - - /** - * Manage a file download. - * - * @param unknown_type $plugin - * @param unknown_type $file_guid If not specified then file_guid will be found in input. - */ - function file_manage_download($plugin, $file_guid = "") { - // Get the guid - $file_guid = (int)$file_guid; - - if (!$file_guid) - $file_guid = (int)get_input("file_guid"); - - // Get the file - $file = get_entity($file_guid); - - if ($file) - { - $mime = $file->getMimeType(); - if (!$mime) $mime = "application/octet-stream"; - - $filename = $file->originalfilename; - - header("Content-type: $mime"); - if (strpos($mime, "image/")!==false) - header("Content-Disposition: inline; filename=\"$filename\""); - else - header("Content-Disposition: attachment; filename=\"$filename\""); - - echo $file->grabFile(); - exit; + + $filename = $file->thumbnail; + + header("Content-type: $mime"); + if (strpos($mime, "image/")!==false) { + header("Content-Disposition: inline; filename=\"$filename\""); + } else { + header("Content-Disposition: attachment; filename=\"$filename\""); } - else - register_error(elgg_echo("$plugin:downloadfailed")); - } - - /** - * Manage the download of a file icon. - * - * @param unknown_type $plugin - * @param unknown_type $file_guid The guid, if not specified this is obtained from the input. - */ - function file_manage_icon_download($plugin, $file_guid = "") { - // Get the guid - $file_guid = (int)$file_guid; - - if (!$file_guid) - $file_guid = (int)get_input("file_guid"); - - // Get the file - $file = get_entity($file_guid); - - if ($file) + + $readfile = new ElggFile(); + $readfile->owner_guid = $file->owner_guid; + $readfile->setFilename($filename); + + /* + if ($file->open("read")); { - $mime = $file->getMimeType(); - if (!$mime) $mime = "application/octet-stream"; - - $filename = $file->thumbnail; - - header("Content-type: $mime"); - if (strpos($mime, "image/")!==false) - header("Content-Disposition: inline; filename=\"$filename\""); - else - header("Content-Disposition: attachment; filename=\"$filename\""); - - - $readfile = new ElggFile(); - $readfile->owner_guid = $file->owner_guid; - $readfile->setFilename($filename); - - /* - if ($file->open("read")); + while (!$file->eof()) { - while (!$file->eof()) - { - echo $file->read(10240, $file->tell()); - } + echo $file->read(10240, $file->tell()); } - */ - - $contents = $readfile->grabFile(); - if (empty($contents)) { - echo file_get_contents(dirname(dirname(__FILE__)) . "/graphics/icons/general.jpg" ); + } + */ + + $contents = $readfile->grabFile(); + if (empty($contents)) { + echo file_get_contents(dirname(dirname(__FILE__)) . "/graphics/icons/general.jpg" ); + } else { + echo $contents; + } + exit; + } else { + register_error(elgg_echo("$plugin:downloadfailed")); + } +} + +function file_display_thumbnail($file_guid,$size) { + // Get file entity + if ($file = get_entity($file_guid)) { + $simpletype = $file->simpletype; + if ($simpletype == "image") { + // Get file thumbnail + if ($size == "small") { + $thumbfile = $file->smallthumb; } else { + $thumbfile = $file->largethumb; + } + + // Grab the file + if ($thumbfile && !empty($thumbfile)) { + $readfile = new ElggFile(); + $readfile->owner_guid = $file->owner_guid; + $readfile->setFilename($thumbfile); + $mime = $file->getMimeType(); + $contents = $readfile->grabFile(); + + header("Content-type: $mime"); echo $contents; + exit; } - exit; - } - else - register_error(elgg_echo("$plugin:downloadfailed")); - } - - function file_display_thumbnail($file_guid,$size) { - // Get file entity - if ($file = get_entity($file_guid)) { - $simpletype = $file->simpletype; - if ($simpletype == "image") { - // Get file thumbnail - if ($size == "small") { - $thumbfile = $file->smallthumb; - } else { - $thumbfile = $file->largethumb; - } - - // Grab the file - if ($thumbfile && !empty($thumbfile)) { - $readfile = new ElggFile(); - $readfile->owner_guid = $file->owner_guid; - $readfile->setFilename($thumbfile); - $mime = $file->getMimeType(); - $contents = $readfile->grabFile(); - - header("Content-type: $mime"); - echo $contents; - exit; - - } - } } } - - function file_set_page_owner($file) { - $page_owner = page_owner_entity(); - if ($page_owner === false || is_null($page_owner)) { - $container_guid = $file->container_guid; - if (!empty($container_guid)) - if ($page_owner = get_entity($container_guid)) { - set_page_owner($page_owner->guid); - } - if (empty($page_owner)) { - $page_owner = $_SESSION['user']; - set_page_owner($_SESSION['guid']); +} + +function file_set_page_owner($file) { + $page_owner = page_owner_entity(); + if ($page_owner === false || is_null($page_owner)) { + $container_guid = $file->container_guid; + if (!empty($container_guid)) { + if ($page_owner = get_entity($container_guid)) { + set_page_owner($page_owner->guid); } } - } - /// Variable holding the default datastore - $DEFAULT_FILE_STORE = NULL; - - /** - * Return the default filestore. - * - * @return ElggFilestore - */ - function get_default_filestore() - { - global $DEFAULT_FILE_STORE; - - return $DEFAULT_FILE_STORE; - } - - /** - * Set the default filestore for the system. - */ - function set_default_filestore(ElggFilestore $filestore) - { - global $DEFAULT_FILE_STORE; - - $DEFAULT_FILE_STORE = $filestore; - - return true; + if (empty($page_owner)) { + $page_owner = $_SESSION['user']; + set_page_owner($_SESSION['guid']); + } } +} - /** - * Run once and only once. - */ - function filestore_run_once() - { - // Register a class - add_subtype("object", "file", "ElggFile"); - } - - /** - * Initialise the file modules. - * Listens to system boot and registers any appropriate file types and classes - */ - function filestore_init() - { - global $CONFIG; - - // Now register a default filestore - set_default_filestore(new ElggDiskFilestore($CONFIG->dataroot)); - - // Now run this stuff, but only once - run_function_once("filestore_run_once"); - } - - // Register a startup event - register_elgg_event_handler('init','system','filestore_init',100); -?> +/// Variable holding the default datastore +$DEFAULT_FILE_STORE = NULL; + +/** + * Return the default filestore. + * + * @return ElggFilestore + */ +function get_default_filestore() { + global $DEFAULT_FILE_STORE; + + return $DEFAULT_FILE_STORE; +} + +/** + * Set the default filestore for the system. + */ +function set_default_filestore(ElggFilestore $filestore) { + global $DEFAULT_FILE_STORE; + + $DEFAULT_FILE_STORE = $filestore; + + return true; +} + +/** + * Run once and only once. + */ +function filestore_run_once() { + // Register a class + add_subtype("object", "file", "ElggFile"); +} + +/** + * Initialise the file modules. + * Listens to system boot and registers any appropriate file types and classes + */ +function filestore_init() { + global $CONFIG; + + // Now register a default filestore + set_default_filestore(new ElggDiskFilestore($CONFIG->dataroot)); + + // Now run this stuff, but only once + run_function_once("filestore_run_once"); +} + +// Register a startup event +register_elgg_event_handler('init', 'system', 'filestore_init', 100); \ No newline at end of file diff --git a/engine/lib/group.php b/engine/lib/group.php index 2941855f7..664837a27 100644 --- a/engine/lib/group.php +++ b/engine/lib/group.php @@ -1,937 +1,970 @@ attributes['type'] = "group"; + $this->attributes['name'] = ""; + $this->attributes['description'] = ""; + $this->attributes['tables_split'] = 2; + } /** - * @class ElggGroup Class representing a container for other elgg entities. - * @author Curverider Ltd + * Construct a new user entity, optionally from a given id value. + * + * @param mixed $guid If an int, load that GUID. + * If a db row then will attempt to load the rest of the data. + * @throws Exception if there was a problem creating the user. */ - class ElggGroup extends ElggEntity - implements Friendable - { - protected function initialise_attributes() - { - parent::initialise_attributes(); - - $this->attributes['type'] = "group"; - $this->attributes['name'] = ""; - $this->attributes['description'] = ""; - $this->attributes['tables_split'] = 2; - } - - /** - * Construct a new user entity, optionally from a given id value. - * - * @param mixed $guid If an int, load that GUID. - * If a db row then will attempt to load the rest of the data. - * @throws Exception if there was a problem creating the user. - */ - function __construct($guid = null) - { - $this->initialise_attributes(); - - if (!empty($guid)) - { - // Is $guid is a DB row - either a entity row, or a user table row. - if ($guid instanceof stdClass) { - // Load the rest - if (!$this->load($guid->guid)) - throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid)); + function __construct($guid = null) { + $this->initialise_attributes(); + + if (!empty($guid)) { + // Is $guid is a DB row - either a entity row, or a user table row. + if ($guid instanceof stdClass) { + // Load the rest + if (!$this->load($guid->guid)) { + throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid)); } - - // Is $guid is an ElggGroup? Use a copy constructor - else if ($guid instanceof ElggGroup) - { - foreach ($guid->attributes as $key => $value) - $this->attributes[$key] = $value; + } + // Is $guid is an ElggGroup? Use a copy constructor + else if ($guid instanceof ElggGroup) { + foreach ($guid->attributes as $key => $value) { + $this->attributes[$key] = $value; } - - // Is this is an ElggEntity but not an ElggGroup = ERROR! - else if ($guid instanceof ElggEntity) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggGroup')); - - // We assume if we have got this far, $guid is an int - else if (is_numeric($guid)) { - if (!$this->load($guid)) IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid)); + } + // Is this is an ElggEntity but not an ElggGroup = ERROR! + else if ($guid instanceof ElggEntity) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggGroup')); + } + // We assume if we have got this far, $guid is an int + else if (is_numeric($guid)) { + if (!$this->load($guid)) { + IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid)); } - - else - throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue')); } - } - - /** - * Add an ElggObject to this group. - * - * @param ElggObject $object The object. - * @return bool - */ - public function addObjectToGroup(ElggObject $object) - { - return add_object_to_group($this->getGUID(), $object->getGUID()); - } - - /** - * Remove an object from the containing group. - * - * @param int $guid The guid of the object. - * @return bool - */ - public function removeObjectFromGroup($guid) - { - return remove_object_from_group($this->getGUID(), $guid); - } - - public function get($name) { - - if ($name == 'username') { - return 'group:' . $this->getGUID(); + + else { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue')); } - return parent::get($name); - } - + } + /** - * Start friendable compatibility block: - * - * public function addFriend($friend_guid); - public function removeFriend($friend_guid); - public function isFriend(); - public function isFriendsWith($user_guid); - public function isFriendOf($user_guid); - public function getFriends($subtype = "", $limit = 10, $offset = 0); - public function getFriendsOf($subtype = "", $limit = 10, $offset = 0); - public function getObjects($subtype="", $limit = 10, $offset = 0); - public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0); - public function countObjects($subtype = ""); + * Add an ElggObject to this group. + * + * @param ElggObject $object The object. + * @return bool */ - - /** - * For compatibility with Friendable - */ - public function addFriend($friend_guid) { - return $this->join(get_entity($friend_guid)); - } - - /** - * For compatibility with Friendable - */ - public function removeFriend($friend_guid) { - return $this->leave(get_entity($friend_guid)); - } + public function addObjectToGroup(ElggObject $object) { + return add_object_to_group($this->getGUID(), $object->getGUID()); + } - /** - * For compatibility with Friendable - */ - public function isFriend() { - return $this->isMember(); - } - - /** - * For compatibility with Friendable - */ - public function isFriendsWith($user_guid) { - return $this->isMember($user_guid); - } - - /** - * For compatibility with Friendable - */ - public function isFriendOf($user_guid) { - return $this->isMember($user_guid); - } - - /** - * For compatibility with Friendable - */ - public function getFriends($subtype = "", $limit = 10, $offset = 0) { - return get_group_members($this->getGUID(), $limit, $offset); - } - - /** - * For compatibility with Friendable - */ - public function getFriendsOf($subtype = "", $limit = 10, $offset = 0) { - return get_group_members($this->getGUID(), $limit, $offset); - } - - /** - * Get objects contained in this group. - * - * @param string $subtype - * @param int $limit - * @param int $offset - * @return mixed - */ - public function getObjects($subtype="", $limit = 10, $offset = 0) - { - return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", $limit, $offset, false); - } - - /** - * For compatibility with Friendable - */ - public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) { - return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", $limit, $offset, false); - } - - /** - * For compatibility with Friendable - */ - public function countObjects($subtype = "") { - return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", 10, 0, true); - } - /** - * End friendable compatibility block + * Remove an object from the containing group. + * + * @param int $guid The guid of the object. + * @return bool */ - - /** - * Get a list of group members. - * - * @param int $limit - * @param int $offset - * @return mixed - */ - public function getMembers($limit = 10, $offset = 0, $count = false) - { - return get_group_members($this->getGUID(), $limit, $offset, 0 , $count); - } + public function removeObjectFromGroup($guid) { + return remove_object_from_group($this->getGUID(), $guid); + } - - - /** - * Returns whether the current group is public membership or not. - * @return bool - */ - public function isPublicMembership() - { - if ($this->membership == ACCESS_PUBLIC) - return true; - - return false; - } - - /** - * Return whether a given user is a member of this group or not. - * - * @param ElggUser $user The user - * @return bool - */ - public function isMember($user = 0) - { - if (!($user instanceof ElggUser)) $user = get_loggedin_user(); - if (!($user instanceof ElggUser)) return false; - return is_group_member($this->getGUID(), $user->getGUID()); - } - - /** - * Join an elgg user to this group. - * - * @param ElggUser $user - * @return bool - */ - public function join(ElggUser $user) - { - return join_group($this->getGUID(), $user->getGUID()); - } - - /** - * Remove a user from the group. - * - * @param ElggUser $user - */ - public function leave(ElggUser $user) - { - return leave_group($this->getGUID(), $user->getGUID()); - } - - /** - * Override the load function. - * This function will ensure that all data is loaded (were possible), so - * if only part of the ElggGroup is loaded, it'll load the rest. - * - * @param int $guid - */ - protected function load($guid) - { - // Test to see if we have the generic stuff - if (!parent::load($guid)) - return false; - - // Check the type - if ($this->attributes['type']!='group') - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class())); - - // Load missing data - $row = get_group_entity_as_row($guid); - if (($row) && (!$this->isFullyLoaded())) $this->attributes['tables_loaded'] ++; // If $row isn't a cached copy then increment the counter - - // Now put these into the attributes array as core values - $objarray = (array) $row; - foreach($objarray as $key => $value) - $this->attributes[$key] = $value; - - return true; - } - - /** - * Override the save function. - */ - public function save() - { - // Save generic stuff - if (!parent::save()) - return false; - - // Now save specific stuff - return create_group_entity($this->get('guid'), $this->get('name'), $this->get('description')); - } - - // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// - - /** - * Return an array of fields which can be exported. - */ - public function getExportableValues() - { - return array_merge(parent::getExportableValues(), array( - 'name', - 'description', - )); + public function get($name) { + if ($name == 'username') { + return 'group:' . $this->getGUID(); } + return parent::get($name); } +/** + * Start friendable compatibility block: + * + * public function addFriend($friend_guid); + public function removeFriend($friend_guid); + public function isFriend(); + public function isFriendsWith($user_guid); + public function isFriendOf($user_guid); + public function getFriends($subtype = "", $limit = 10, $offset = 0); + public function getFriendsOf($subtype = "", $limit = 10, $offset = 0); + public function getObjects($subtype="", $limit = 10, $offset = 0); + public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0); + public function countObjects($subtype = ""); + */ + /** - * Get the group entity. - * - * @param int $guid + * For compatibility with Friendable */ - function get_group_entity_as_row($guid) - { - global $CONFIG; - - $guid = (int)$guid; - - /*$row = retrieve_cached_entity_row($guid); - if ($row) - { - // We have already cached this object, so retrieve its value from the cache - if (isset($CONFIG->debug) && $CONFIG->debug) - error_log("** Retrieving sub part of GUID:$guid from cache"); - - return $row; - } - else - {*/ - // Object not cached, load it. - if (isset($CONFIG->debug) && $CONFIG->debug == true) - error_log("** Sub part of GUID:$guid loaded from DB"); - - return get_data_row("SELECT * from {$CONFIG->dbprefix}groups_entity where guid=$guid"); - //} + public function addFriend($friend_guid) { + return $this->join(get_entity($friend_guid)); } /** - * Create or update the extras table for a given group. - * Call create_entity first. - * - * @param int $guid - * @param string $name - * @param string $description + * For compatibility with Friendable */ - function create_group_entity($guid, $name, $description) - { - global $CONFIG; - - $guid = (int)$guid; - $name = sanitise_string($name); - $description = sanitise_string($description); - - $row = get_entity_as_row($guid); - - if ($row) - { - // Exists and you have access to it - if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}groups_entity WHERE guid = {$guid}")) { - $result = update_data("UPDATE {$CONFIG->dbprefix}groups_entity set name='$name', description='$description' where guid=$guid"); - if ($result!=false) - { - // Update succeeded, continue - $entity = get_entity($guid); - if (trigger_elgg_event('update',$entity->type,$entity)) { - return $guid; - } else { - $entity->delete(); - //delete_entity($guid); - } - } - } - else - { - // Update failed, attempt an insert. - $result = insert_data("INSERT into {$CONFIG->dbprefix}groups_entity (guid, name, description) values ($guid, '$name','$description')"); - if ($result!==false) { - $entity = get_entity($guid); - if (trigger_elgg_event('create',$entity->type,$entity)) { - return $guid; - } else { - $entity->delete(); - //delete_entity($guid); - } - } - } - } - - return false; + public function removeFriend($friend_guid) { + return $this->leave(get_entity($friend_guid)); } - - + /** - * THIS FUNCTION IS DEPRECATED. - * - * Delete a group's extra data. - * - * @param int $guid The guid of the group - * @return bool + * For compatibility with Friendable */ - function delete_group_entity($guid) - { - system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity')); - - return 1; // Always return that we have deleted one row in order to not break existing code. + public function isFriend() { + return $this->isMember(); } - + /** - * Add an object to the given group. - * - * @param int $group_guid The group to add the object to. - * @param int $object_guid The guid of the elgg object (must be ElggObject or a child thereof) - * @return bool + * For compatibility with Friendable */ - function add_object_to_group($group_guid, $object_guid) - { - $group_guid = (int)$group_guid; - $object_guid = (int)$object_guid; - - $group = get_entity($group_guid); - $object = get_entity($object_guid); - - if ((!$group) || (!$object)) return false; - - if (!($group instanceof ElggGroup)) - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $group_guid, 'ElggGroup')); - - if (!($object instanceof ElggObject)) - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $object_guid, 'ElggObject')); - - $object->container_guid = $group_guid; - return $object->save(); - } - + public function isFriendsWith($user_guid) { + return $this->isMember($user_guid); + } + /** - * Remove an object from the given group. - * - * @param int $group_guid The group to remove the object from - * @param int $object_guid The object to remove + * For compatibility with Friendable */ - function remove_object_from_group($group_guid, $object_guid) - { - $group_guid = (int)$group_guid; - $object_guid = (int)$object_guid; - - $group = get_entity($group_guid); - $object = get_entity($object_guid); - - if ((!$group) || (!$object)) return false; - - if (!($group instanceof ElggGroup)) - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $group_guid, 'ElggGroup')); - - if (!($object instanceof ElggObject)) - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $object_guid, 'ElggObject')); - - $object->container_guid = $object->owner_guid; - return $object->save(); - } - + public function isFriendOf($user_guid) { + return $this->isMember($user_guid); + } + /** - * Return an array of objects in a given container. - * @see get_entities() - * - * @param int $group_guid The container (defaults to current page owner) - * @param string $subtype The subtype - * @param int $owner_guid Owner - * @param int $site_guid The site - * @param string $order_by Order - * @param unknown_type $limit Limit on number of elements to return, by default 10. - * @param unknown_type $offset Where to start, by default 0. - * @param unknown_type $count Whether to return the entities or a count of them. + * For compatibility with Friendable */ - function get_objects_in_group($group_guid, $subtype = "", $owner_guid = 0, $site_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false) - { - global $CONFIG; - - if ($subtype === false || $subtype === null || $subtype === 0) - return false; - - $subtype = get_subtype_id('object', $subtype); - - if ($order_by == "") $order_by = "e.time_created desc"; - $order_by = sanitise_string($order_by); - $limit = (int)$limit; - $offset = (int)$offset; - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - $container_guid = (int)$group_guid; - if ($container_guid == 0) - $container_guid = page_owner(); - - $where = array(); - - $where[] = "e.type='object'"; - if ($subtype!=="") - $where[] = "e.subtype=$subtype"; - if ($owner_guid != "") { - if (!is_array($owner_guid)) { - $owner_guid = (int) $owner_guid; - $where[] = "e.container_guid = '$owner_guid'"; - } else if (sizeof($owner_guid) > 0) { - // Cast every element to the owner_guid array to int - $owner_guid = array_map("sanitise_int", $owner_guid); - $owner_guid = implode(",",$owner_guid); - $where[] = "e.container_guid in ({$owner_guid})"; - } - } - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - - if ($container_guid > 0) - $where[] = "e.container_guid = {$container_guid}"; - - if (!$count) { - $query = "SELECT * from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where "; - } else { - $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where "; - } - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix('e'); // Add access controls - if (!$count) { - $query .= " order by $order_by"; - if ($limit) $query .= " limit $offset, $limit"; // Add order and limit - - $dt = get_data($query, "entity_row_to_elggstar"); - return $dt; - } else { - $total = get_data_row($query); - return $total->total; - } + public function getFriends($subtype = "", $limit = 10, $offset = 0) { + return get_group_members($this->getGUID(), $limit, $offset); } - + /** - * Get all the entities from metadata from a group. - * - * @param int $group_guid The ID of the group. - * @param mixed $meta_name - * @param mixed $meta_value - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity. - * @param int $limit - * @param int $offset - * @param string $order_by Optional ordering. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) + * For compatibility with Friendable */ - function get_entities_from_metadata_groups($group_guid, $meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) - { - global $CONFIG; - - $meta_n = get_metastring_id($meta_name); - $meta_v = get_metastring_id($meta_value); - - $entity_type = sanitise_string($entity_type); - $entity_subtype = get_subtype_id($entity_type, $entity_subtype); - $limit = (int)$limit; - $offset = (int)$offset; - if ($order_by == "") $order_by = "e.time_created desc"; - $order_by = sanitise_string($order_by); - $site_guid = (int) $site_guid; - if (is_array($owner_guid)) { - foreach($owner_guid as $key => $guid) { - $owner_guid[$key] = (int) $guid; - } - } else { - $owner_guid = (int) $owner_guid; - } - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - $container_guid = (int)$group_guid; - if ($container_guid == 0) - $container_guid = page_owner(); - - //$access = get_access_list(); - - $where = array(); - - if ($entity_type!="") - $where[] = "e.type='$entity_type'"; - if ($entity_subtype) - $where[] = "e.subtype=$entity_subtype"; - if ($meta_name!="") - $where[] = "m.name_id='$meta_n'"; - if ($meta_value!="") - $where[] = "m.value_id='$meta_v'"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - if ($container_guid > 0) - $where[] = "e.container_guid = {$container_guid}"; - if (is_array($owner_guid)) { - $where[] = "e.container_guid in (".implode(",",$owner_guid).")"; - } else if ($owner_guid > 0) - $where[] = "e.container_guid = {$owner_guid}"; - - if (!$count) { - $query = "SELECT distinct e.* "; - } else { - $query = "SELECT count(e.guid) as total "; - } - - $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid join {$CONFIG->dbprefix}objects_entity o on e.guid = o.guid where"; - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); - } else { - if ($row = get_data_row($query)) - return $row->total; - } - return false; + public function getFriendsOf($subtype = "", $limit = 10, $offset = 0) { + return get_group_members($this->getGUID(), $limit, $offset); } - + /** - * As get_entities_from_metadata_groups() but with multiple entities. + * Get objects contained in this group. * - * @param int $group_guid The ID of the group. - * @param array $meta_array Array of 'name' => 'value' pairs - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity. - * @param int $limit + * @param string $subtype + * @param int $limit * @param int $offset - * @param string $order_by Optional ordering. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) - * @return int|array List of ElggEntities, or the total number if count is set to false + * @return mixed */ - function get_entities_from_metadata_groups_multi($group_guid, $meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) - { - global $CONFIG; - - if (!is_array($meta_array) || sizeof($meta_array) == 0) { - return false; - } - - $where = array(); - - $mindex = 1; - $join = ""; - foreach($meta_array as $meta_name => $meta_value) { - $meta_n = get_metastring_id($meta_name); - $meta_v = get_metastring_id($meta_value); - $join .= " JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid join {$CONFIG->dbprefix}objects_entity o on e.guid = o.guid "; - if ($meta_name!="") - $where[] = "m{$mindex}.name_id='$meta_n'"; - if ($meta_value!="") - $where[] = "m{$mindex}.value_id='$meta_v'"; - $mindex++; - } - - $entity_type = sanitise_string($entity_type); - $entity_subtype = get_subtype_id($entity_type, $entity_subtype); - $limit = (int)$limit; - $offset = (int)$offset; - if ($order_by == "") $order_by = "e.time_created desc"; - $order_by = sanitise_string($order_by); - $owner_guid = (int) $owner_guid; - - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - //$access = get_access_list(); - - if ($entity_type!="") - $where[] = "e.type = '{$entity_type}'"; - if ($entity_subtype) - $where[] = "e.subtype = {$entity_subtype}"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - if ($owner_guid > 0) - $where[] = "e.owner_guid = {$owner_guid}"; - if ($container_guid > 0) - $where[] = "e.container_guid = {$container_guid}"; - - if ($count) { - $query = "SELECT count(e.guid) as total "; - } else { - $query = "SELECT distinct e.* "; - } - - $query .= " from {$CONFIG->dbprefix}entities e {$join} where"; - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); - } else { - if ($count = get_data_row($query)) { - return $count->total; - } - } - return false; + public function getObjects($subtype="", $limit = 10, $offset = 0) { + return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", $limit, $offset, false); + } + + /** + * For compatibility with Friendable + */ + public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) { + return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", $limit, $offset, false); } - + + /** + * For compatibility with Friendable + */ + public function countObjects($subtype = "") { + return get_objects_in_group($this->getGUID(), $subtype, 0, 0, "", 10, 0, true); + } + +/** + * End friendable compatibility block + */ + /** - * Return a list of this group's members. - * - * @param int $group_guid The ID of the container/group. - * @param int $limit The limit - * @param int $offset The offset - * @param int $site_guid The site - * @param bool $count Return the users (false) or the count of them (true) + * Get a list of group members. + * + * @param int $limit + * @param int $offset * @return mixed */ - function get_group_members($group_guid, $limit = 10, $offset = 0, $site_guid = 0, $count = false) - { - return get_entities_from_relationship('member', $group_guid, true, 'user', '', 0, "", $limit, $offset, $count, $site_guid); + public function getMembers($limit = 10, $offset = 0, $count = false) { + return get_group_members($this->getGUID(), $limit, $offset, 0 , $count); } - + /** - * Return whether a given user is a member of the group or not. - * - * @param int $group_guid The group ID - * @param int $user_guid The user guid + * Returns whether the current group is public membership or not. * @return bool */ - function is_group_member($group_guid, $user_guid) - { - return check_entity_relationship($user_guid, 'member', $group_guid); + public function isPublicMembership() { + if ($this->membership == ACCESS_PUBLIC) { + return true; + } + + return false; } - + /** - * Join a user to a group. - * - * @param int $group_guid The group. - * @param int $user_guid The user. + * Return whether a given user is a member of this group or not. + * + * @param ElggUser $user The user + * @return bool */ - function join_group($group_guid, $user_guid) - { - $result = add_entity_relationship($user_guid, 'member', $group_guid); - trigger_elgg_event('join','group',array('group' => get_entity($group_guid), 'user' => get_entity($user_guid))); - return $result; + public function isMember($user = 0) { + if (!($user instanceof ElggUser)) { + $user = get_loggedin_user(); + } + if (!($user instanceof ElggUser)) { + return false; + } + return is_group_member($this->getGUID(), $user->getGUID()); } - + /** - * Remove a user from a group. - * - * @param int $group_guid The group. - * @param int $user_guid The user. + * Join an elgg user to this group. + * + * @param ElggUser $user + * @return bool */ - function leave_group($group_guid, $user_guid) - { - $result = remove_entity_relationship($user_guid, 'member', $group_guid); - trigger_elgg_event('leave','group',array('group' => get_entity($group_guid), 'user' => get_entity($user_guid))); - return $result; + public function join(ElggUser $user) { + return join_group($this->getGUID(), $user->getGUID()); } - + /** - * Return all groups a user is a member of. + * Remove a user from the group. * - * @param unknown_type $user_guid + * @param ElggUser $user */ - function get_users_membership($user_guid) - { - return get_entities_from_relationship('member', $user_guid, false); + public function leave(ElggUser $user) { + return leave_group($this->getGUID(), $user->getGUID()); } - + /** - * Checks access to a group. + * Override the load function. + * This function will ensure that all data is loaded (were possible), so + * if only part of the ElggGroup is loaded, it'll load the rest. * - * @param boolean $forward If set to true (default), will forward the page; if set to false, will return true or false. - * @return true|false If $forward is set to false. + * @param int $guid */ - function group_gatekeeper($forward = true) { - - $allowed = true; - $url = ''; - - if ($group = page_owner_entity()) { - if ($group instanceof ElggGroup) { - $url = $group->getURL(); - if ( - ((!isloggedin()) && (!$group->isPublicMembership())) || - ((!$group->isMember(get_loggedin_user()) && (!$group->isPublicMembership()))) - ) $allowed = false; - - // Admin override - if (isadminloggedin()) $allowed = true; - } + protected function load($guid) { + // Test to see if we have the generic stuff + if (!parent::load($guid)) { + return false; } - - if ($forward && $allowed == false) { - forward($url); - exit; + + // Check the type + if ($this->attributes['type']!='group') { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class())); + } + + // Load missing data + $row = get_group_entity_as_row($guid); + if (($row) && (!$this->isFullyLoaded())) { + // If $row isn't a cached copy then increment the counter + $this->attributes['tables_loaded'] ++; + } + + // Now put these into the attributes array as core values + $objarray = (array) $row; + foreach($objarray as $key => $value) { + $this->attributes[$key] = $value; } - - return $allowed; - + + return true; } - + /** - * Manages group tool options - * - * @param string $name Name of the group tool option - * @param string $label Used for the group edit form - * @param boolean $default_on True if this option should be active by default - * - **/ - - function add_group_tool_option($name,$label,$default_on=true) { - global $CONFIG; - - if (!isset($CONFIG->group_tool_options)) { - $CONFIG->group_tool_options = array(); + * Override the save function. + */ + public function save() { + // Save generic stuff + if (!parent::save()) { + return false; } - - $group_tool_option = new stdClass; - - $group_tool_option->name = $name; - $group_tool_option->label = $label; - $group_tool_option->default_on = $default_on; - - $CONFIG->group_tool_options[] = $group_tool_option; - } - + + // Now save specific stuff + return create_group_entity($this->get('guid'), $this->get('name'), $this->get('description')); + } + + // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// + /** - * Searches for a group based on a complete or partial name or description - * - * @param string $criteria The partial or full name or description - * @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 an array of fields which can be exported. */ - function search_for_group($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) + public function getExportableValues() { + return array_merge(parent::getExportableValues(), array( + 'name', + 'description', + )); + } +} + +/** + * Get the group entity. + * + * @param int $guid + */ +function get_group_entity_as_row($guid) { + global $CONFIG; + + $guid = (int)$guid; + + /*$row = retrieve_cached_entity_row($guid); + if ($row) { - global $CONFIG; - - $criteria = sanitise_string($criteria); - $limit = (int)$limit; - $offset = (int)$offset; - $order_by = sanitise_string($order_by); - - $access = get_access_sql_suffix("e"); - - 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 join {$CONFIG->dbprefix}groups_entity g on e.guid=g.guid where "; - // $query .= " match(u.name,u.username) against ('$criteria') "; - $query .= "(g.name like \"%{$criteria}%\" or g.description like \"%{$criteria}%\")"; - $query .= " and $access"; - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); + // We have already cached this object, so retrieve its value from the cache + if (isset($CONFIG->debug) && $CONFIG->debug) + error_log("** Retrieving sub part of GUID:$guid from cache"); + + return $row; + } + else + {*/ + // Object not cached, load it. + if (isset($CONFIG->debug) && $CONFIG->debug == true) { + error_log("** Sub part of GUID:$guid loaded from DB"); + } + + return get_data_row("SELECT * from {$CONFIG->dbprefix}groups_entity where guid=$guid"); + //} +} + +/** + * Create or update the extras table for a given group. + * Call create_entity first. + * + * @param int $guid + * @param string $name + * @param string $description + */ +function create_group_entity($guid, $name, $description) { + global $CONFIG; + + $guid = (int)$guid; + $name = sanitise_string($name); + $description = sanitise_string($description); + + $row = get_entity_as_row($guid); + + if ($row) { + // Exists and you have access to it + if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}groups_entity WHERE guid = {$guid}")) { + $result = update_data("UPDATE {$CONFIG->dbprefix}groups_entity set name='$name', description='$description' where guid=$guid"); + if ($result!=false) { + // Update succeeded, continue + $entity = get_entity($guid); + if (trigger_elgg_event('update',$entity->type,$entity)) { + return $guid; + } else { + $entity->delete(); + //delete_entity($guid); + } + } } else { - if ($count = get_data_row($query)) { - return $count->total; + // Update failed, attempt an insert. + $result = insert_data("INSERT into {$CONFIG->dbprefix}groups_entity (guid, name, description) values ($guid, '$name','$description')"); + if ($result!==false) { + $entity = get_entity($guid); + if (trigger_elgg_event('create',$entity->type,$entity)) { + return $guid; + } else { + $entity->delete(); + //delete_entity($guid); + } } } + } + + return false; +} + + +/** + * THIS FUNCTION IS DEPRECATED. + * + * Delete a group's extra data. + * + * @param int $guid The guid of the group + * @return bool + */ +function delete_group_entity($guid) { + system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity')); + + // Always return that we have deleted one row in order to not break existing code. + return 1; +} + +/** + * Add an object to the given group. + * + * @param int $group_guid The group to add the object to. + * @param int $object_guid The guid of the elgg object (must be ElggObject or a child thereof) + * @return bool + */ +function add_object_to_group($group_guid, $object_guid) { + $group_guid = (int)$group_guid; + $object_guid = (int)$object_guid; + + $group = get_entity($group_guid); + $object = get_entity($object_guid); + + if ((!$group) || (!$object)) { return false; } - - /** - * Returns a formatted list of groups suitable for injecting into search. - * - */ - function search_list_groups_by_name($hook, $user, $returnvalue, $tag) { - // Change this to set the number of groups that display on the search page - $threshold = 4; + if (!($group instanceof ElggGroup)) { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $group_guid, 'ElggGroup')); + } + + if (!($object instanceof ElggObject)) { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $object_guid, 'ElggObject')); + } + + $object->container_guid = $group_guid; + return $object->save(); +} + +/** + * Remove an object from the given group. + * + * @param int $group_guid The group to remove the object from + * @param int $object_guid The object to remove + */ +function remove_object_from_group($group_guid, $object_guid) { + $group_guid = (int)$group_guid; + $object_guid = (int)$object_guid; + + $group = get_entity($group_guid); + $object = get_entity($object_guid); + + if ((!$group) || (!$object)) { + return false; + } + + if (!($group instanceof ElggGroup)) { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $group_guid, 'ElggGroup')); + } + + if (!($object instanceof ElggObject)) { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $object_guid, 'ElggObject')); + } + + $object->container_guid = $object->owner_guid; + return $object->save(); +} + +/** + * Return an array of objects in a given container. + * @see get_entities() + * + * @param int $group_guid The container (defaults to current page owner) + * @param string $subtype The subtype + * @param int $owner_guid Owner + * @param int $site_guid The site + * @param string $order_by Order + * @param unknown_type $limit Limit on number of elements to return, by default 10. + * @param unknown_type $offset Where to start, by default 0. + * @param unknown_type $count Whether to return the entities or a count of them. + */ +function get_objects_in_group($group_guid, $subtype = "", $owner_guid = 0, $site_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false) { + global $CONFIG; + + if ($subtype === false || $subtype === null || $subtype === 0) { + return false; + } + + $subtype = get_subtype_id('object', $subtype); + + if ($order_by == "") { + $order_by = "e.time_created desc"; + } + $order_by = sanitise_string($order_by); + $limit = (int)$limit; + $offset = (int)$offset; + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + $container_guid = (int)$group_guid; + if ($container_guid == 0) { + $container_guid = page_owner(); + } + + $where = array(); + + $where[] = "e.type='object'"; + if ($subtype!=="") { + $where[] = "e.subtype=$subtype"; + } + if ($owner_guid != "") { + if (!is_array($owner_guid)) { + $owner_guid = (int) $owner_guid; + $where[] = "e.container_guid = '$owner_guid'"; + } else if (sizeof($owner_guid) > 0) { + // Cast every element to the owner_guid array to int + $owner_guid = array_map("sanitise_int", $owner_guid); + $owner_guid = implode(",",$owner_guid); + $where[] = "e.container_guid in ({$owner_guid})"; + } + } + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + if ($container_guid > 0) { + $where[] = "e.container_guid = {$container_guid}"; + } + + if (!$count) { + $query = "SELECT * from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where "; + } else { + $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where "; + } + foreach ($where as $w) { + $query .= " $w and "; + } + + // Add access controls + $query .= get_access_sql_suffix('e'); + if (!$count) { + $query .= " order by $order_by"; + + // Add order and limit + if ($limit) { + $query .= " limit $offset, $limit"; + } + + $dt = get_data($query, "entity_row_to_elggstar"); + return $dt; + } else { + $total = get_data_row($query); + return $total->total; + } +} + +/** + * Get all the entities from metadata from a group. + * + * @param int $group_guid The ID of the group. + * @param mixed $meta_name + * @param mixed $meta_value + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity. + * @param int $limit + * @param int $offset + * @param string $order_by Optional ordering. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) + */ +function get_entities_from_metadata_groups($group_guid, $meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) { + global $CONFIG; + + $meta_n = get_metastring_id($meta_name); + $meta_v = get_metastring_id($meta_value); + + $entity_type = sanitise_string($entity_type); + $entity_subtype = get_subtype_id($entity_type, $entity_subtype); + $limit = (int)$limit; + $offset = (int)$offset; + if ($order_by == "") { + $order_by = "e.time_created desc"; + } + $order_by = sanitise_string($order_by); + $site_guid = (int) $site_guid; + if (is_array($owner_guid)) { + foreach($owner_guid as $key => $guid) { + $owner_guid[$key] = (int) $guid; + } + } else { + $owner_guid = (int) $owner_guid; + } + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + $container_guid = (int)$group_guid; + if ($container_guid == 0) { + $container_guid = page_owner(); + } + + //$access = get_access_list(); + + $where = array(); + + if ($entity_type!="") { + $where[] = "e.type='$entity_type'"; + } + if ($entity_subtype) { + $where[] = "e.subtype=$entity_subtype"; + } + if ($meta_name!="") { + $where[] = "m.name_id='$meta_n'"; + } + if ($meta_value!="") { + $where[] = "m.value_id='$meta_v'"; + } + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + if ($container_guid > 0) { + $where[] = "e.container_guid = {$container_guid}"; + } + + if (is_array($owner_guid)) { + $where[] = "e.container_guid in (".implode(",",$owner_guid).")"; + } else if ($owner_guid > 0) + $where[] = "e.container_guid = {$owner_guid}"; + + if (!$count) { + $query = "SELECT distinct e.* "; + } else { + $query = "SELECT count(e.guid) as total "; + } + + $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid join {$CONFIG->dbprefix}objects_entity o on e.guid = o.guid where"; + foreach ($where as $w) { + $query .= " $w and "; + } + + // Add access controls + $query .= get_access_sql_suffix("e"); + + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($row = get_data_row($query)) { + return $row->total; + } + } + return false; +} + +/** + * As get_entities_from_metadata_groups() but with multiple entities. + * + * @param int $group_guid The ID of the group. + * @param array $meta_array Array of 'name' => 'value' pairs + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity. + * @param int $limit + * @param int $offset + * @param string $order_by Optional ordering. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) + * @return int|array List of ElggEntities, or the total number if count is set to false + */ +function get_entities_from_metadata_groups_multi($group_guid, $meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) { + global $CONFIG; + + if (!is_array($meta_array) || sizeof($meta_array) == 0) { + return false; + } + + $where = array(); + + $mindex = 1; + $join = ""; + foreach($meta_array as $meta_name => $meta_value) { + $meta_n = get_metastring_id($meta_name); + $meta_v = get_metastring_id($meta_value); + $join .= " JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid join {$CONFIG->dbprefix}objects_entity o on e.guid = o.guid "; + if ($meta_name!="") { + $where[] = "m{$mindex}.name_id='$meta_n'"; + } + + if ($meta_value!="") { + $where[] = "m{$mindex}.value_id='$meta_v'"; + } + + $mindex++; + } + + $entity_type = sanitise_string($entity_type); + $entity_subtype = get_subtype_id($entity_type, $entity_subtype); + $limit = (int)$limit; + $offset = (int)$offset; + if ($order_by == "") { + $order_by = "e.time_created desc"; + } + $order_by = sanitise_string($order_by); + $owner_guid = (int) $owner_guid; + + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + //$access = get_access_list(); + + if ($entity_type!="") { + $where[] = "e.type = '{$entity_type}'"; + } + + if ($entity_subtype) { + $where[] = "e.subtype = {$entity_subtype}"; + } + + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + if ($owner_guid > 0) { + $where[] = "e.owner_guid = {$owner_guid}"; + } + + if ($container_guid > 0) { + $where[] = "e.container_guid = {$container_guid}"; + } + + if ($count) { + $query = "SELECT count(e.guid) as total "; + } else { + $query = "SELECT distinct e.* "; + } + + $query .= " from {$CONFIG->dbprefix}entities e {$join} where"; + foreach ($where as $w) { + $query .= " $w and "; + } + $query .= get_access_sql_suffix("e"); // Add access controls + + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; + } + } + return false; +} + +/** + * Return a list of this group's members. + * + * @param int $group_guid The ID of the container/group. + * @param int $limit The limit + * @param int $offset The offset + * @param int $site_guid The site + * @param bool $count Return the users (false) or the count of them (true) + * @return mixed + */ +function get_group_members($group_guid, $limit = 10, $offset = 0, $site_guid = 0, $count = false) { + return get_entities_from_relationship('member', $group_guid, true, 'user', '', 0, "", $limit, $offset, $count, $site_guid); +} + +/** + * Return whether a given user is a member of the group or not. + * + * @param int $group_guid The group ID + * @param int $user_guid The user guid + * @return bool + */ +function is_group_member($group_guid, $user_guid) { + return check_entity_relationship($user_guid, 'member', $group_guid); +} + +/** + * Join a user to a group. + * + * @param int $group_guid The group. + * @param int $user_guid The user. + */ +function join_group($group_guid, $user_guid) { + $result = add_entity_relationship($user_guid, 'member', $group_guid); + trigger_elgg_event('join', 'group', array('group' => get_entity($group_guid), 'user' => get_entity($user_guid))); + return $result; +} + +/** + * Remove a user from a group. + * + * @param int $group_guid The group. + * @param int $user_guid The user. + */ +function leave_group($group_guid, $user_guid) { + $result = remove_entity_relationship($user_guid, 'member', $group_guid); + trigger_elgg_event('leave', 'group', array('group' => get_entity($group_guid), 'user' => get_entity($user_guid))); + return $result; +} + +/** + * Return all groups a user is a member of. + * + * @param unknown_type $user_guid + */ +function get_users_membership($user_guid) { + return get_entities_from_relationship('member', $user_guid, false); +} - $object = get_input('object'); - - if (!get_input('offset') && (empty($object) || $object == 'group')) +/** + * Checks access to a group. + * + * @param boolean $forward If set to true (default), will forward the page; if set to false, will return true or false. + * @return true|false If $forward is set to false. + */ +function group_gatekeeper($forward = true) { + $allowed = true; + $url = ''; + + if ($group = page_owner_entity()) { + if ($group instanceof ElggGroup) { + $url = $group->getURL(); + if ( + ((!isloggedin()) && (!$group->isPublicMembership())) || + ((!$group->isMember(get_loggedin_user()) && (!$group->isPublicMembership()))) + ) { + $allowed = false; + } + + // Admin override + if (isadminloggedin()) { + $allowed = true; + } + } + } + + if ($forward && $allowed == false) { + forward($url); + exit; + } + + return $allowed; +} + +/** + * Manages group tool options + * + * @param string $name Name of the group tool option + * @param string $label Used for the group edit form + * @param boolean $default_on True if this option should be active by default + * + **/ + +function add_group_tool_option($name,$label,$default_on=true) { + global $CONFIG; + + if (!isset($CONFIG->group_tool_options)) { + $CONFIG->group_tool_options = array(); + } + + $group_tool_option = new stdClass; + + $group_tool_option->name = $name; + $group_tool_option->label = $label; + $group_tool_option->default_on = $default_on; + + $CONFIG->group_tool_options[] = $group_tool_option; +} + +/** + * Searches for a group based on a complete or partial name or description + * + * @param string $criteria The partial or full name or description + * @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. + */ +function search_for_group($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) { + global $CONFIG; + + $criteria = sanitise_string($criteria); + $limit = (int)$limit; + $offset = (int)$offset; + $order_by = sanitise_string($order_by); + + $access = get_access_sql_suffix("e"); + + 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 join {$CONFIG->dbprefix}groups_entity g on e.guid=g.guid where "; + // $query .= " match(u.name,u.username) against ('$criteria') "; + $query .= "(g.name like \"%{$criteria}%\" or g.description like \"%{$criteria}%\")"; + $query .= " and $access"; + + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; + } + } + return false; +} + +/** + * Returns a formatted list of groups suitable for injecting into search. + * + */ +function search_list_groups_by_name($hook, $user, $returnvalue, $tag) { + // Change this to set the number of groups that display on the search page + $threshold = 4; + + $object = get_input('object'); + + if (!get_input('offset') && (empty($object) || $object == 'group')) { if ($groups = search_for_group($tag,$threshold)) { - $countgroups = search_for_group($tag,0,0,"",true); - + $return = elgg_view('group/search/startblurb',array('count' => $countgroups, 'tag' => $tag)); foreach($groups as $group) { $return .= elgg_view_entity($group); } $return .= elgg_view('group/search/finishblurb',array('count' => $countgroups, 'threshold' => $threshold, 'tag' => $tag)); return $return; - } - } - - /** - * Displays a list of group objects that have been searched for. - * - * @see elgg_view_entity_list - * - * @param string $tag Search criteria - * @param int $limit The number of entities to display on a page - * @return string The list in a form suitable to display - */ - function list_group_search($tag, $limit = 10) { - - $offset = (int) get_input('offset'); - $limit = (int) $limit; - $count = (int) search_for_group($tag, 10, 0, '', true); - $entities = search_for_group($tag, $limit, $offset); - - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, false); - - } - - /** - * Performs initialisation functions for groups - * - */ - function group_init() { - // Register an entity type - register_entity_type('group',''); - - // Register a search hook - register_plugin_hook('search','all','search_list_groups_by_name'); - } - - register_elgg_event_handler('init','system','group_init'); - -?> +} + +/** + * Displays a list of group objects that have been searched for. + * + * @see elgg_view_entity_list + * + * @param string $tag Search criteria + * @param int $limit The number of entities to display on a page + * @return string The list in a form suitable to display + */ +function list_group_search($tag, $limit = 10) { + $offset = (int) get_input('offset'); + $limit = (int) $limit; + $count = (int) search_for_group($tag, 10, 0, '', true); + $entities = search_for_group($tag, $limit, $offset); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, false); + +} + +/** + * Performs initialisation functions for groups + * + */ +function group_init() { + // Register an entity type + register_entity_type('group',''); + + // Register a search hook + register_plugin_hook('search','all','search_list_groups_by_name'); +} + +register_elgg_event_handler('init','system','group_init'); diff --git a/engine/lib/input.php b/engine/lib/input.php index 49eb63f13..289542547 100644 --- a/engine/lib/input.php +++ b/engine/lib/input.php @@ -1,376 +1,362 @@ - - * @link http://elgg.org/ - */ - - /** - * Get some input from variables passed on the GET or POST line. - * - * @param $variable string The variable we want to return. - * @param $default mixed A default value for the variable if it is not found. - * @param $filter_result If true then the result is filtered for bad tags. - */ - function get_input($variable, $default = "", $filter_result = true) - { - - global $CONFIG; - - if (isset($CONFIG->input[$variable])) { - $var = $CONFIG->input[$variable]; - - if ($filter_result) - $var = filter_tags($var); - - return $var; +/** + * Parameter input functions. + * This file contains functions for getting input from get/post variables. + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + */ + +/** + * Get some input from variables passed on the GET or POST line. + * + * @param $variable string The variable we want to return. + * @param $default mixed A default value for the variable if it is not found. + * @param $filter_result If true then the result is filtered for bad tags. + */ +function get_input($variable, $default = "", $filter_result = true) { + + global $CONFIG; + + if (isset($CONFIG->input[$variable])) { + $var = $CONFIG->input[$variable]; + + if ($filter_result) { + $var = filter_tags($var); } - - if (isset($_REQUEST[$variable])) { - - if (is_array($_REQUEST[$variable])) { - $var = $_REQUEST[$variable]; - } else { - $var = trim($_REQUEST[$variable]); - } - - if ($filter_result) - $var = filter_tags($var); - return $var; - + return $var; + } + + if (isset($_REQUEST[$variable])) { + if (is_array($_REQUEST[$variable])) { + $var = $_REQUEST[$variable]; + } else { + $var = trim($_REQUEST[$variable]); } - return $default; + if ($filter_result) { + $var = filter_tags($var); + } + return $var; } - - /** - * Sets an input value that may later be retrieved by get_input - * - * @param string $variable The name of the variable - * @param string $value The value of the variable - */ - function set_input($variable, $value) { - - global $CONFIG; - if (!isset($CONFIG->input)) - $CONFIG->input = array(); - - if (is_array($value)) - { - foreach ($value as $key => $val) - $value[$key] = trim($val); - - $CONFIG->input[trim($variable)] = $value; + + return $default; +} + +/** + * Sets an input value that may later be retrieved by get_input + * + * @param string $variable The name of the variable + * @param string $value The value of the variable + */ +function set_input($variable, $value) { + global $CONFIG; + if (!isset($CONFIG->input)) { + $CONFIG->input = array(); + } + + if (is_array($value)) { + foreach ($value as $key => $val) { + $value[$key] = trim($val); } - else - $CONFIG->input[trim($variable)] = trim($value); - + + $CONFIG->input[trim($variable)] = $value; + } else { + $CONFIG->input[trim($variable)] = trim($value); } - - /** - * Filter tags from a given string based on registered hooks. - * @param $var - * @return mixed The filtered result - */ - function filter_tags($var) - { - return trigger_plugin_hook('validate', 'input', null, $var); +} + +/** + * Filter tags from a given string based on registered hooks. + * @param $var + * @return mixed The filtered result + */ +function filter_tags($var) { + return trigger_plugin_hook('validate', 'input', null, $var); +} + +/** + * Sanitise file paths for input, ensuring that they begin and end with slashes etc. + * + * @param string $path The path + * @return string + */ +function sanitise_filepath($path) { + // Convert to correct UNIX paths + $path = str_replace('\\', '/', $path); + + // Sort trailing slash + $path = trim($path); + $path = rtrim($path, " /"); + $path = $path . "/"; + + return $path; +} + + +/** + * Takes a string and turns any URLs into formatted links + * + * @param string $text The input string + * @return string The output stirng with formatted links + **/ +function parse_urls($text) { + return preg_replace_callback('/(?"\'\!\(\)]+)/i', + create_function( + '$matches', + ' + $url = $matches[1]; + $urltext = str_replace("/", "/", $url); + return "$urltext"; + ' + ), $text); +} + +function autop($pee, $br = 1) { + $pee = $pee . "\n"; // just to make things a little easier, pad the end + $pee = preg_replace('|
\s*
|', "\n\n", $pee); + // Space things out a little + $allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)'; + $pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee); + $pee = preg_replace('!()!', "$1\n\n", $pee); + $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines + if ( strpos($pee, ']*)>\s*|', "", $pee); // no pee inside object/embed + $pee = preg_replace('|\s*\s*|', '', $pee); } - - /** - * Sanitise file paths for input, ensuring that they begin and end with slashes etc. - * - * @param string $path The path - * @return string - */ - function sanitise_filepath($path) - { - // Convert to correct UNIX paths - $path = str_replace('\\', '/', $path); - - // Sort trailing slash - $path = trim($path); - $path = rtrim($path, " /"); - $path = $path . "/"; - - return $path; + $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates + $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "

$1

\n", $pee); // make paragraphs, including one at the end + $pee = preg_replace('|

\s*?

|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace + $pee = preg_replace('!

([^<]+)\s*?(]*>)!', "

$1

$2", $pee); + $pee = preg_replace( '|

|', "$1

", $pee ); + $pee = preg_replace('!

\s*(]*>)\s*

!', "$1", $pee); // don't pee all over a tag + $pee = preg_replace("|

(|", "$1", $pee); // problem with nested lists + $pee = preg_replace('|

]*)>|i', "

", $pee); + $pee = str_replace('

', '

', $pee); + $pee = preg_replace('!

\s*(]*>)!', "$1", $pee); + $pee = preg_replace('!(]*>)\s*

!', "$1", $pee); + if ($br) { + $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "", $matches[0]);'), $pee); + $pee = preg_replace('|(?)\s*\n|', "
\n", $pee); // optionally make line breaks + $pee = str_replace('', "\n", $pee); } - - - /** - * Takes a string and turns any URLs into formatted links - * - * @param string $text The input string - * @return string The output stirng with formatted links - **/ - function parse_urls($text) { - - return preg_replace_callback('/(?"\'\!\(\)]+)/i', - create_function( - '$matches', - ' - $url = $matches[1]; - $urltext = str_replace("/", "/", $url); - return "$urltext"; - ' - ), $text); - } - - function autop($pee, $br = 1) { - $pee = $pee . "\n"; // just to make things a little easier, pad the end - $pee = preg_replace('|
\s*
|', "\n\n", $pee); - // Space things out a little - $allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)'; - $pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee); - $pee = preg_replace('!()!', "$1\n\n", $pee); - $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines - if ( strpos($pee, ']*)>\s*|', "", $pee); // no pee inside object/embed - $pee = preg_replace('|\s*\s*|', '', $pee); - } - $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates - $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "

$1

\n", $pee); // make paragraphs, including one at the end - $pee = preg_replace('|

\s*?

|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace - $pee = preg_replace('!

([^<]+)\s*?(]*>)!', "

$1

$2", $pee); - $pee = preg_replace( '|

|', "$1

", $pee ); - $pee = preg_replace('!

\s*(]*>)\s*

!', "$1", $pee); // don't pee all over a tag - $pee = preg_replace("|

(|", "$1", $pee); // problem with nested lists - $pee = preg_replace('|

]*)>|i', "

", $pee); - $pee = str_replace('

', '

', $pee); - $pee = preg_replace('!

\s*(]*>)!', "$1", $pee); - $pee = preg_replace('!(]*>)\s*

!', "$1", $pee); - if ($br) { - $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "", $matches[0]);'), $pee); - $pee = preg_replace('|(?)\s*\n|', "
\n", $pee); // optionally make line breaks - $pee = str_replace('', "\n", $pee); - } - $pee = preg_replace('!(]*>)\s*
!', "$1", $pee); - $pee = preg_replace('!
(\s*]*>)!', '$1', $pee); - if (strpos($pee, ')(.*?)!is', 'clean_pre', $pee ); - $pee = preg_replace( "|\n

$|", '

', $pee ); - - return $pee; + $pee = preg_replace('!(]*>)\s*
!', "$1", $pee); + $pee = preg_replace('!
(\s*]*>)!', '$1', $pee); + if (strpos($pee, ')(.*?)!is', 'clean_pre', $pee ); } - - /** - * Page handler for autocomplete endpoint. - * - * @param $page - * @return unknown_type - */ - function input_livesearch_page_handler($page) { - global $CONFIG; - // only return results to logged in users. - if (!$user = get_loggedin_user()) { - exit; - } - - if (!$q = get_input('q')) { - exit; - } + $pee = preg_replace( "|\n

$|", '

', $pee ); - $q = mysql_real_escape_string($q); + return $pee; +} - // replace mysql vars with escaped strings - $q = str_replace(array('_', '%'), array('\_', '\%'), $q); - - $match_on = get_input('match_on', 'all'); - if ($match_on == 'all' || $match_on[0] == 'all') { - $match_on = array('users', 'groups'); - } - - if (!is_array($match_on)) { - $match_on = array($match_on); - } - - if (get_input('match_owner', false)) { - $owner_guid = $user->getGUID(); - $owner_where = 'AND e.owner_guid = ' . $user->getGUID(); - } else { - $owner_guid = null; - $owner_where = ''; - } - - $limit = get_input('limit', 10); - - // grab a list of entities and send them in json. - $results = array(); - foreach ($match_on as $type) { - switch ($type) { - case 'all': - // only need to pull up title from objects. - - if (!$entities = get_entities(null, null, $owner_guid, null, $limit) AND is_array($entities)) { - $results = array_merge($results, $entities); - } - break; - - 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.username LIKE '$q%') - LIMIT $limit - "; - - if ($entities = get_data($query)) { - foreach ($entities as $entity) { - $json = json_encode(array( - 'type' => 'user', - 'name' => $entity->name, - 'desc' => $entity->username, - 'icon' => '', - 'guid' => $entity->guid - )); - $results[$entity->name . rand(1,100)] = $json; - } +/** + * Page handler for autocomplete endpoint. + * + * @param $page + * @return unknown_type + */ +function input_livesearch_page_handler($page) { + global $CONFIG; + // only return results to logged in users. + if (!$user = get_loggedin_user()) { + exit; + } + + if (!$q = get_input('q')) { + exit; + } + + $q = mysql_real_escape_string($q); + + // replace mysql vars with escaped strings + $q = str_replace(array('_', '%'), array('\_', '\%'), $q); + + $match_on = get_input('match_on', 'all'); + if ($match_on == 'all' || $match_on[0] == 'all') { + $match_on = array('users', 'groups'); + } + + if (!is_array($match_on)) { + $match_on = array($match_on); + } + + if (get_input('match_owner', false)) { + $owner_guid = $user->getGUID(); + $owner_where = 'AND e.owner_guid = ' . $user->getGUID(); + } else { + $owner_guid = null; + $owner_where = ''; + } + + $limit = get_input('limit', 10); + + // grab a list of entities and send them in json. + $results = array(); + foreach ($match_on as $type) { + switch ($type) { + case 'all': + // only need to pull up title from objects. + + if (!$entities = get_entities(null, null, $owner_guid, null, $limit) AND is_array($entities)) { + $results = array_merge($results, $entities); + } + break; + + 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.username LIKE '$q%') + LIMIT $limit + "; + + if ($entities = get_data($query)) { + foreach ($entities as $entity) { + $json = json_encode(array( + 'type' => 'user', + 'name' => $entity->name, + 'desc' => $entity->username, + 'icon' => '', + 'guid' => $entity->guid + )); + $results[$entity->name . rand(1,100)] = $json; } - break; - - case 'groups': - // don't return results if groups aren't enabled. - if (!is_plugin_enabled('groups')) { - continue; + } + break; + + case 'groups': + // don't return results if groups aren't enabled. + if (!is_plugin_enabled('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.description LIKE '%$q%') + LIMIT $limit + "; + if ($entities = get_data($query)) { + foreach ($entities as $entity) { + $json = json_encode(array( + 'type' => 'group', + 'name' => $entity->name, + 'desc' => strip_tags($entity->description), + 'icon' => '', + 'guid' => $entity->guid + )); + //$results[$entity->name . rand(1,100)] = "$json|{$entity->guid}"; + $results[$entity->name . rand(1,100)] = $json; } - $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.description LIKE '%$q%') - LIMIT $limit - "; - if ($entities = get_data($query)) { - foreach ($entities as $entity) { - $json = json_encode(array( - 'type' => 'group', - 'name' => $entity->name, - 'desc' => strip_tags($entity->description), - 'icon' => '', - 'guid' => $entity->guid - )); - //$results[$entity->name . rand(1,100)] = "$json|{$entity->guid}"; - $results[$entity->name . rand(1,100)] = $json; - } + } + break; + + case 'friends': + $access = get_access_sql_suffix(); + $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.username LIKE '$q%') + LIMIT $limit + "; + + if ($entities = get_data($query)) { + foreach ($entities as $entity) { + $json = json_encode(array( + 'type' => 'user', + 'name' => $entity->name, + 'desc' => $entity->username, + 'icon' => '', + 'guid' => $entity->guid + )); + $results[$entity->name . rand(1,100)] = $json; } - break; - - case 'friends': - $access = get_access_sql_suffix(); - $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.username LIKE '$q%') - LIMIT $limit - "; - - if ($entities = get_data($query)) { - foreach ($entities as $entity) { - $json = json_encode(array( - 'type' => 'user', - 'name' => $entity->name, - 'desc' => $entity->username, - 'icon' => '', - 'guid' => $entity->guid - )); - $results[$entity->name . rand(1,100)] = $json; - } + } + break; + + default: + // arbitrary subtype. + get_entities(null, $type, $owner_guid); + break; + } + } + + ksort($results); + echo implode($results, "\n"); + exit; +} + + +function input_init() { + // register an endpoint for live search / autocomplete. + register_page_handler('livesearch', 'input_livesearch_page_handler'); + + if (ini_get_bool('magic_quotes_gpc') ) { + //do keys as well, cos array_map ignores them + 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; } - break; - - default: - // arbitrary subtype. - get_entities(null, $type, $owner_guid); - break; + } + return $array2; + } else { + return $array; } } - - ksort($results); - echo implode($results, "\n"); - exit; - } - - function input_init() { - - // register an endpoint for live search / autocomplete. - register_page_handler('livesearch', 'input_livesearch_page_handler'); - - if (ini_get_bool('magic_quotes_gpc') ) { - - //do keys as well, cos array_map ignores them - 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; - } - } - - 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']); - } - + 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']); } - } - - register_elgg_event_handler('init','system','input_init'); - - -?> +} + +register_elgg_event_handler('init','system','input_init'); \ No newline at end of file diff --git a/engine/lib/install.php b/engine/lib/install.php index 03abede14..1b363b950 100644 --- a/engine/lib/install.php +++ b/engine/lib/install.php @@ -1,126 +1,117 @@ =')) && - (version_compare(phpversion(), '5.2.0', '<')) - ) - register_error(elgg_echo('configurationwarning:phpversion')); - */ - - if (version_compare(phpversion(), '5.1.2', '>=')) - return true; - +/** + * Elgg installation + * Various functions to assist with installing and upgrading the system + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + */ + +/** + * Check that the installed version of PHP meets the minimum requirements (currently 5.2 or greater). + * + * @return bool + */ +function php_check_version() { + if (version_compare(phpversion(), '5.1.2', '>=')) { + return true; + } + + return false; +} + +/** + * Validate the platform Elgg is being installed on. + * + * @throws ConfigurationException if the validation fails. + * @return bool + */ +function validate_platform() { + // Get database version + if (!db_check_version()) { + throw new ConfigurationException(elgg_echo('ConfigurationException:BadDatabaseVersion')); + } + + // Now check PHP + if (!php_check_version()) { + throw new ConfigurationException(elgg_echo('ConfigurationException:BadPHPVersion')); + } + + // TODO: Consider checking for installed modules etc + return true; +} + +/** + * Returns whether or not the database has been installed + * + * @return true|false Whether the database has been installed + */ +function is_db_installed() { + global $CONFIG; + + if (isset($CONFIG->db_installed)) { + return $CONFIG->db_installed; + } + + if ($dblink = get_db_link('read')) { + mysql_query("select name from {$CONFIG->dbprefix}datalists limit 1", $dblink); + if (mysql_errno($dblink) > 0) { return false; } - - /** - * Validate the platform Elgg is being installed on. - * - * @throws ConfigurationException if the validation fails. - * @return bool - */ - function validate_platform() - { - // Get database version - if (!db_check_version()) - throw new ConfigurationException(elgg_echo('ConfigurationException:BadDatabaseVersion')); - - // Now check PHP - if (!php_check_version()) - throw new ConfigurationException(elgg_echo('ConfigurationException:BadPHPVersion')); - - // TODO: Consider checking for installed modules etc - - return true; - } + } else { + return false; + } - /** - * Returns whether or not the database has been installed - * - * @return true|false Whether the database has been installed - */ - function is_db_installed() { - - global $CONFIG; - - if (isset($CONFIG->db_installed)) { - return $CONFIG->db_installed; - } - - if ($dblink = get_db_link('read')) { - mysql_query("select name from {$CONFIG->dbprefix}datalists limit 1",$dblink); - if (mysql_errno($dblink) > 0) return false; - } else return false; - - $CONFIG->db_installed = true; // Set flag if db is installed (if false then we want to check every time) - - return true; - - } - - /** - * Returns whether or not other settings have been set - * - * @return true|false Whether or not the rest of the installation has been followed through with - */ - function is_installed() { - - global $CONFIG; - return datalist_get('installed'); - - } - - /** - * Copy and create a new settings.php from settings.example.php, substituting the variables in - * $vars where appropriate. - * - * $vars is an associate array of $key => $value, where $key is the variable text you wish to substitute (eg - * CONFIG_DBNAME will replace {{CONFIG_DBNAME}} in the settings file. - * - * @param array $vars The array of vars - * @param string $in_file Optional input file (if not settings.example.php) - * @return string The file containing substitutions. - */ - function create_settings(array $vars, $in_file="engine/settings.example.php") - { - $file = file_get_contents($in_file); - - if (!$file) return false; - - foreach ($vars as $k => $v) - $file = str_replace("{{".$k."}}", $v, $file); - - return $file; - } - - /** - * Initialisation for installation functions - * - */ - function install_init() { - register_action("systemsettings/install",true); - } - - register_elgg_event_handler("boot","system","install_init"); - -?> \ No newline at end of file + // Set flag if db is installed (if false then we want to check every time) + $CONFIG->db_installed = true; + + return true; +} + +/** + * Returns whether or not other settings have been set + * + * @return true|false Whether or not the rest of the installation has been followed through with + */ +function is_installed() { + global $CONFIG; + return datalist_get('installed'); +} + +/** + * Copy and create a new settings.php from settings.example.php, substituting the variables in + * $vars where appropriate. + * + * $vars is an associate array of $key => $value, where $key is the variable text you wish to substitute (eg + * CONFIG_DBNAME will replace {{CONFIG_DBNAME}} in the settings file. + * + * @param array $vars The array of vars + * @param string $in_file Optional input file (if not settings.example.php) + * @return string The file containing substitutions. + */ +function create_settings(array $vars, $in_file="engine/settings.example.php") { + $file = file_get_contents($in_file); + + if (!$file) { + return false; + } + + foreach ($vars as $k => $v) { + $file = str_replace("{{".$k."}}", $v, $file); + } + + return $file; +} + +/** + * Initialisation for installation functions + * + */ +function install_init() { + register_action("systemsettings/install",true); +} + +register_elgg_event_handler("boot","system","install_init"); \ No newline at end of file diff --git a/engine/lib/languages.php b/engine/lib/languages.php index dd97d0927..19f3c138a 100644 --- a/engine/lib/languages.php +++ b/engine/lib/languages.php @@ -1,252 +1,246 @@ 'message1', 'message2' => 'message2'); - * $german = array('message1' => 'Nachricht1','message2' => 'Nachricht2'); - * - * @param string $country_code Standard country code (eg 'en', 'nl', 'es') - * @param array $language_array Formatted array of strings - * @return true|false Depending on success - */ - - function add_translation($country_code, $language_array) { - - global $CONFIG; - if (!isset($CONFIG->translations)) - $CONFIG->translations = array(); - - $country_code = strtolower($country_code); - $country_code = trim($country_code); - if (is_array($language_array) && sizeof($language_array) > 0 && $country_code != "") { - - if (!isset($CONFIG->translations[$country_code])) { - $CONFIG->translations[$country_code] = $language_array; - } else { - $CONFIG->translations[$country_code] = $language_array + $CONFIG->translations[$country_code]; - } - - return true; - - } - return false; - +/** + * Add a translation. + * + * Translations are arrays in the Zend Translation array format, eg: + * + * $english = array('message1' => 'message1', 'message2' => 'message2'); + * $german = array('message1' => 'Nachricht1','message2' => 'Nachricht2'); + * + * @param string $country_code Standard country code (eg 'en', 'nl', 'es') + * @param array $language_array Formatted array of strings + * @return true|false Depending on success + */ +function add_translation($country_code, $language_array) { + global $CONFIG; + if (!isset($CONFIG->translations)) { + $CONFIG->translations = array(); + } + + $country_code = strtolower($country_code); + $country_code = trim($country_code); + if (is_array($language_array) && sizeof($language_array) > 0 && $country_code != "") { + if (!isset($CONFIG->translations[$country_code])) { + $CONFIG->translations[$country_code] = $language_array; + } else { + $CONFIG->translations[$country_code] = $language_array + $CONFIG->translations[$country_code]; } - - /** - * Detect the current language being used by the current site or logged in user. - * - */ - function get_current_language() - { - global $CONFIG; - - $language = get_language(); - - if (!$language) - $language = 'en'; - + return true; + } + return false; +} + +/** + * Detect the current language being used by the current site or logged in user. + * + */ +function get_current_language() { + global $CONFIG; + + $language = get_language(); + + if (!$language) { + $language = 'en'; + } + + return $language; +} + +/** + * Gets the current language in use by the system or user. + * + * [Marcus Povey 20090216: Not sure why this func is necessary.] + * + * @return string The language code (eg "en") + */ +function get_language() { + global $CONFIG; + + $user = get_loggedin_user(); + $language = false; + + if (($user) && ($user->language)) { + $language = $user->language; + } + + if ((!$language) && (isset($CONFIG->language)) && ($CONFIG->language)) { + $language = $CONFIG->language; + } + + if ($language) { return $language; } - - /** - * Gets the current language in use by the system or user. - * - * [Marcus Povey 20090216: Not sure why this func is necessary.] - * - * @return string The language code (eg "en") - */ - function get_language() { - - global $CONFIG; - - $user = get_loggedin_user(); - $language = false; - - if (($user) && ($user->language)) - $language = $user->language; - - if ((!$language) && (isset($CONFIG->language)) && ($CONFIG->language)) - $language = $CONFIG->language; - - if ($language) { - return $language; - } - return false; - - } - - /** - * Given a message shortcode, returns an appropriately translated full-text string - * - * @param string $message_key The short message code - * @param string $language Optionally, the standard language code (defaults to the site default, then English) - * @return string Either the translated string, or the original English string, or an empty string - */ - function elgg_echo($message_key, $language = "") { - - global $CONFIG; - - static $CURRENT_LANGUAGE; - if ((!$CURRENT_LANGUAGE) && (!$language)) - $CURRENT_LANGUAGE = $language = get_language(); - else - $language = $CURRENT_LANGUAGE; - - if (isset($CONFIG->translations[$language][$message_key])) { - return $CONFIG->translations[$language][$message_key]; - } else if (isset($CONFIG->translations["en"][$message_key])) { - return $CONFIG->translations["en"][$message_key]; - } - - return $message_key; - - } - - /** - * When given a full path, finds translation files and loads them - * - * @param string $path Full path - * @param bool $load_all If true all languages are loaded, if false only the current language + en are loaded - */ - function register_translations($path, $load_all = false) { - global $CONFIG; - - // Make a note of this path just incase we need to register this language later - if(!isset($CONFIG->language_paths)) $CONFIG->language_paths = array(); - $CONFIG->language_paths[$path] = true; - - // Get the current language based on site defaults and user preference - $current_language = get_current_language(); - - if (isset($CONFIG->debug) && $CONFIG->debug == true) error_log("Translations loaded from : $path"); - - if ($handle = opendir($path)) { - while ($language = readdir($handle)) { - - if ( - ((in_array($language, array('en.php', $current_language . '.php'))) /*&& (!is_dir($path . $language))*/) || - (($load_all) && (strpos($language, '.php')!==false)/* && (!is_dir($path . $language))*/) - ) - include_once($path . $language); - - } - } - else - error_log("Missing translation path $path"); - - } - - /** - * Reload all translations from all registered paths. - * - * This is only called by functions which need to know all possible translations, namely the - * statistic gathering ones. - * - * TODO: Better on demand loading based on language_paths array - * - * @return bool - */ - function reload_all_translations() - { - global $CONFIG; - - static $LANG_RELOAD_ALL_RUN; - if ($LANG_RELOAD_ALL_RUN) return null; - - foreach ($CONFIG->language_paths as $path => $dummy) - register_translations($path, true); - - $LANG_RELOAD_ALL_RUN = true; - } - - /** - * Return an array of installed translations as an associative array "two letter code" => "native language name". - */ - function get_installed_translations() - { - global $CONFIG; - - // Ensure that all possible translations are loaded - reload_all_translations(); - - $installed = array(); - - foreach ($CONFIG->translations as $k => $v) - { - $installed[$k] = elgg_echo($k, $k); - - $completeness = get_language_completeness($k); - if ((isadminloggedin()) && ($completeness<100) && ($k!='en')) - $installed[$k] .= " (" . $completeness . "% " . elgg_echo('complete') . ")"; + + return false; +} + +/** + * Given a message shortcode, returns an appropriately translated full-text string + * + * @param string $message_key The short message code + * @param string $language Optionally, the standard language code (defaults to the site default, then English) + * @return string Either the translated string, or the original English string, or an empty string + */ +function elgg_echo($message_key, $language = "") { + global $CONFIG; + + static $CURRENT_LANGUAGE; + if ((!$CURRENT_LANGUAGE) && (!$language)) { + $CURRENT_LANGUAGE = $language = get_language(); + } else { + $language = $CURRENT_LANGUAGE; + } + + if (isset($CONFIG->translations[$language][$message_key])) { + return $CONFIG->translations[$language][$message_key]; + } else if (isset($CONFIG->translations["en"][$message_key])) { + return $CONFIG->translations["en"][$message_key]; + } + + return $message_key; +} + +/** + * When given a full path, finds translation files and loads them + * + * @param string $path Full path + * @param bool $load_all If true all languages are loaded, if false only the current language + en are loaded + */ +function register_translations($path, $load_all = false) { + global $CONFIG; + + // Make a note of this path just incase we need to register this language later + if(!isset($CONFIG->language_paths)) $CONFIG->language_paths = array(); + $CONFIG->language_paths[$path] = true; + + // Get the current language based on site defaults and user preference + $current_language = get_current_language(); + + if (isset($CONFIG->debug) && $CONFIG->debug == true) { + error_log("Translations loaded from : $path"); + } + + if ($handle = opendir($path)) { + while ($language = readdir($handle)) { + if ( + ((in_array($language, array('en.php', $current_language . '.php'))) /*&& (!is_dir($path . $language))*/) || + (($load_all) && (strpos($language, '.php')!==false)/* && (!is_dir($path . $language))*/) + ) { + include_once($path . $language); } - - return $installed; } - - /** - * Return the level of completeness for a given language code (compared to english) - */ - function get_language_completeness($language) - { - global $CONFIG; - - // Ensure that all possible translations are loaded - reload_all_translations(); - - $language = sanitise_string($language); - - $en = count($CONFIG->translations['en']); - - $missing = get_missing_language_keys($language); - if ($missing) $missing = count($missing); else $missing = 0; - - //$lang = count($CONFIG->translations[$language]); - $lang = $en - $missing; - - return round(($lang / $en) * 100, 2); + } else { + error_log("Missing translation path $path"); + } +} + +/** + * Reload all translations from all registered paths. + * + * This is only called by functions which need to know all possible translations, namely the + * statistic gathering ones. + * + * TODO: Better on demand loading based on language_paths array + * + * @return bool + */ +function reload_all_translations() { + global $CONFIG; + + static $LANG_RELOAD_ALL_RUN; + if ($LANG_RELOAD_ALL_RUN) { + return null; + } + + foreach ($CONFIG->language_paths as $path => $dummy) { + register_translations($path, true); + } + + $LANG_RELOAD_ALL_RUN = true; +} + +/** + * Return an array of installed translations as an associative array "two letter code" => "native language name". + */ +function get_installed_translations() { + global $CONFIG; + + // Ensure that all possible translations are loaded + reload_all_translations(); + + $installed = array(); + + foreach ($CONFIG->translations as $k => $v) { + $installed[$k] = elgg_echo($k, $k); + + $completeness = get_language_completeness($k); + if ((isadminloggedin()) && ($completeness<100) && ($k!='en')) { + $installed[$k] .= " (" . $completeness . "% " . elgg_echo('complete') . ")"; } - - /** - * Return the translation keys missing from a given language, or those that are identical to the english version. - */ - function get_missing_language_keys($language) - { - global $CONFIG; - - // Ensure that all possible translations are loaded - reload_all_translations(); - - $missing = array(); - - foreach ($CONFIG->translations['en'] as $k => $v) - { - if ((!isset($CONFIG->translations[$language][$k])) - || ($CONFIG->translations[$language][$k] == $CONFIG->translations['en'][$k])) - $missing[] = $k; - } - - if (count($missing)) - return $missing; - - return false; + } + + return $installed; +} + +/** + * Return the level of completeness for a given language code (compared to english) + */ +function get_language_completeness($language) { + global $CONFIG; + + // Ensure that all possible translations are loaded + reload_all_translations(); + + $language = sanitise_string($language); + + $en = count($CONFIG->translations['en']); + + $missing = get_missing_language_keys($language); + if ($missing) { + $missing = count($missing); + } else { + $missing = 0; + } + + //$lang = count($CONFIG->translations[$language]); + $lang = $en - $missing; + + return round(($lang / $en) * 100, 2); +} + +/** + * Return the translation keys missing from a given language, or those that are identical to the english version. + */ +function get_missing_language_keys($language) { + global $CONFIG; + + // Ensure that all possible translations are loaded + reload_all_translations(); + + $missing = array(); + + foreach ($CONFIG->translations['en'] as $k => $v) { + if ((!isset($CONFIG->translations[$language][$k])) + || ($CONFIG->translations[$language][$k] == $CONFIG->translations['en'][$k])) { + $missing[] = $k; } - - register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/"); - -?> \ No newline at end of file + } + + if (count($missing)) { + return $missing; + } + + return false; +} + +register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/"); \ No newline at end of file diff --git a/engine/lib/location.php b/engine/lib/location.php index 0edada0ae..21ee7d5fa 100644 --- a/engine/lib/location.php +++ b/engine/lib/location.php @@ -1,131 +1,130 @@ geo:lat field. * */ - interface Locatable - { - /** Set a location text */ - public function setLocation($location); - - /** - * Set latitude and longitude tags for a given entity. - * - * @param float $lat - * @param float $long - */ - public function setLatLong($lat, $long); - - /** - * Get the contents of the ->geo:lat field. - * - */ - public function getLatitude(); - - /** - * Get the contents of the ->geo:lat field. - * - */ - public function getLongitude(); - - /** - * Get the ->location metadata. - * - */ - public function getLocation(); - } + public function getLatitude(); /** - * Encode a location into a latitude and longitude, caching the result. + * Get the contents of the ->geo:lat field. * - * Works by triggering the 'geocode' 'location' plugin hook, and requires a geocoding module to be installed - * activated in order to work. - * - * @param String $location The location, e.g. "London", or "24 Foobar Street, Gotham City" */ - function elgg_geocode_location($location) - { - global $CONFIG; - - // Handle cases where we are passed an array (shouldn't be but can happen if location is a tag field) - if (is_array($location)) - $location = implode(', ', $location); - - $location = sanitise_string($location); - - // Look for cached version - $cached_location = get_data_row("SELECT * from {$CONFIG->dbprefix}geocode_cache WHERE location='$location'"); - - if ($cached_location) - return array('lat' => $cached_location->lat, 'long' => $cached_location->long); - - // Trigger geocode event if not cached - $return = false; - $return = trigger_plugin_hook('geocode', 'location', array('location' => $location), $return); - - // If returned, cache and return value - if (($return) && (is_array($return))) - { - $lat = (float)$return['lat']; - $long = (float)$return['long']; - - // Put into cache at the end of the page since we don't really care that much - execute_delayed_write_query("INSERT DELAYED INTO {$CONFIG->dbprefix}geocode_cache (location, lat, `long`) VALUES ('$location', '{$lat}', '{$long}') ON DUPLICATE KEY UPDATE lat='{$lat}', `long`='{$long}'"); - } - - return $return; - } - + public function getLongitude(); + /** - * Return entities within a given geographic area. + * Get the ->location metadata. * - * @param real $lat Latitude - * @param real $long Longitude - * @param real $radius The radius - * @param string $type The type of entity (eg "user", "object" etc) - * @param string $subtype The arbitrary subtype of the entity - * @param int $owner_guid The GUID of the owning user - * @param string $order_by The field to order by; by default, time_created desc - * @param int $limit The number of entities to return; 10 by default - * @param int $offset The indexing offset, 0 by default - * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @param int|array $container_guid The container or containers to get entities from (default: all containers). - * @return array A list of entities. */ - function get_entities_in_area($lat, $long, $radius, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid) - { - global $CONFIG; - - if ($subtype === false || $subtype === null || $subtype === 0) - return false; - - $lat = (real)$lat; - $long = (real)$long; - $radius = (real)$radius; - - $order_by = sanitise_string($order_by); - $limit = (int)$limit; - $offset = (int)$offset; - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - $where = array(); - - if (is_array($type)) { - $tempwhere = ""; - if (sizeof($type)) + public function getLocation(); +} + +/** + * Encode a location into a latitude and longitude, caching the result. + * + * Works by triggering the 'geocode' 'location' plugin hook, and requires a geocoding module to be installed + * activated in order to work. + * + * @param String $location The location, e.g. "London", or "24 Foobar Street, Gotham City" + */ +function elgg_geocode_location($location) { + global $CONFIG; + + // Handle cases where we are passed an array (shouldn't be but can happen if location is a tag field) + if (is_array($location)) { + $location = implode(', ', $location); + } + + $location = sanitise_string($location); + + // Look for cached version + $cached_location = get_data_row("SELECT * from {$CONFIG->dbprefix}geocode_cache WHERE location='$location'"); + + if ($cached_location) { + return array('lat' => $cached_location->lat, 'long' => $cached_location->long); + } + + // Trigger geocode event if not cached + $return = false; + $return = trigger_plugin_hook('geocode', 'location', array('location' => $location), $return); + + // If returned, cache and return value + if (($return) && (is_array($return))) { + $lat = (float)$return['lat']; + $long = (float)$return['long']; + + // Put into cache at the end of the page since we don't really care that much + execute_delayed_write_query("INSERT DELAYED INTO {$CONFIG->dbprefix}geocode_cache (location, lat, `long`) VALUES ('$location', '{$lat}', '{$long}') ON DUPLICATE KEY UPDATE lat='{$lat}', `long`='{$long}'"); + } + + return $return; +} + +/** + * Return entities within a given geographic area. + * + * @param real $lat Latitude + * @param real $long Longitude + * @param real $radius The radius + * @param string $type The type of entity (eg "user", "object" etc) + * @param string $subtype The arbitrary subtype of the entity + * @param int $owner_guid The GUID of the owning user + * @param string $order_by The field to order by; by default, time_created desc + * @param int $limit The number of entities to return; 10 by default + * @param int $offset The indexing offset, 0 by default + * @param boolean $count Set to true to get a count rather than the entities themselves (limits and offsets don't apply in this context). Defaults to false. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param int|array $container_guid The container or containers to get entities from (default: all containers). + * @return array A list of entities. + */ +function get_entities_in_area($lat, $long, $radius, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0, $container_guid) { + global $CONFIG; + + if ($subtype === false || $subtype === null || $subtype === 0) { + return false; + } + + $lat = (real)$lat; + $long = (real)$long; + $radius = (real)$radius; + + $order_by = sanitise_string($order_by); + $limit = (int)$limit; + $offset = (int)$offset; + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + $where = array(); + + if (is_array($type)) { + $tempwhere = ""; + if (sizeof($type)) { foreach($type as $typekey => $subtypearray) { foreach($subtypearray as $subtypeval) { $typekey = sanitise_string($typekey); @@ -136,145 +135,148 @@ } if (!empty($tempwhere)) $tempwhere .= " or "; $tempwhere .= "(e.type = '{$typekey}' and e.subtype = {$subtypeval})"; - } + } } - if (!empty($tempwhere)) $where[] = "({$tempwhere})"; - - } else { - - $type = sanitise_string($type); - $subtype = get_subtype_id($type, $subtype); - - if ($type != "") - $where[] = "e.type='$type'"; - if ($subtype!=="") - $where[] = "e.subtype=$subtype"; - } + if (!empty($tempwhere)) { + $where[] = "({$tempwhere})"; + } + } else { + $type = sanitise_string($type); + $subtype = get_subtype_id($type, $subtype); - if ($owner_guid != "") { - if (!is_array($owner_guid)) { - $owner_array = array($owner_guid); - $owner_guid = (int) $owner_guid; - $where[] = "e.owner_guid = '$owner_guid'"; - } else if (sizeof($owner_guid) > 0) { - $owner_array = array_map('sanitise_int', $owner_guid); - // Cast every element to the owner_guid array to int - $owner_guid = implode(",",$owner_guid); // - $where[] = "e.owner_guid in ({$owner_guid})" ; // - } - if (is_null($container_guid)) { - $container_guid = $owner_array; - } + if ($type != "") { + $where[] = "e.type='$type'"; } - - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - - if (!is_null($container_guid)) { - if (is_array($container_guid)) { - foreach($container_guid as $key => $val) $container_guid[$key] = (int) $val; - $where[] = "e.container_guid in (" . implode(",",$container_guid) . ")"; - } else { - $container_guid = (int) $container_guid; - $where[] = "e.container_guid = {$container_guid}"; - } - } - - // Add the calendar stuff - $loc_join = " - JOIN {$CONFIG->dbprefix}metadata loc_start on e.guid=loc_start.entity_guid - JOIN {$CONFIG->dbprefix}metastrings loc_start_name on loc_start.name_id=loc_start_name.id - JOIN {$CONFIG->dbprefix}metastrings loc_start_value on loc_start.value_id=loc_start_value.id - - JOIN {$CONFIG->dbprefix}metadata loc_end on e.guid=loc_end.entity_guid - JOIN {$CONFIG->dbprefix}metastrings loc_end_name on loc_end.name_id=loc_end_name.id - JOIN {$CONFIG->dbprefix}metastrings loc_end_value on loc_end.value_id=loc_end_value.id - "; - - $lat_min = $lat - $radius; - $lat_max = $lat + $radius; - $long_min = $long - $radius; - $long_max = $long + $radius; - - $where[] = "loc_start_name.string='geo:lat'"; - $where[] = "loc_start_value.string>=$lat_min"; - $where[] = "loc_start_value.string<=$lat_max"; - $where[] = "loc_end_name.string='geo:long'"; - $where[] = "loc_end_value.string >= $long_min"; - $where[] = "loc_end_value.string <= $long_max"; - - - if (!$count) { - $query = "SELECT e.* from {$CONFIG->dbprefix}entities e $loc_join where "; - } else { - $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e $loc_join where "; + + if ($subtype!=="") { + $where[] = "e.subtype=$subtype"; + } + } + + if ($owner_guid != "") { + if (!is_array($owner_guid)) { + $owner_array = array($owner_guid); + $owner_guid = (int) $owner_guid; + $where[] = "e.owner_guid = '$owner_guid'"; + } else if (sizeof($owner_guid) > 0) { + $owner_array = array_map('sanitise_int', $owner_guid); + // Cast every element to the owner_guid array to int + $owner_guid = implode(",",$owner_guid); // + $where[] = "e.owner_guid in ({$owner_guid})" ; // } - foreach ($where as $w) - $query .= " $w and "; - - $query .= get_access_sql_suffix('e'); // Add access controls - - if (!$count) { - $query .= " order by n.calendar_start $order_by"; - if ($limit) $query .= " limit $offset, $limit"; // Add order and limit - $dt = get_data($query, "entity_row_to_elggstar"); - return $dt; + if (is_null($container_guid)) { + $container_guid = $owner_array; + } + } + + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + if (!is_null($container_guid)) { + if (is_array($container_guid)) { + foreach($container_guid as $key => $val) $container_guid[$key] = (int) $val; + $where[] = "e.container_guid in (" . implode(",",$container_guid) . ")"; } else { - $total = get_data_row($query); - return $total->total; - } + $container_guid = (int) $container_guid; + $where[] = "e.container_guid = {$container_guid}"; + } } - - /** - * List entities in a given location - * - * @param string $location Location - * @param string $type The type of entity (eg "user", "object" etc) - * @param string $subtype The arbitrary subtype of the entity - * @param int $owner_guid The GUID of the owning user - * @param int $limit The number of entities to display per page (default: 10) - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow gallery view - * @param true|false $pagination Display pagination? Default: true - * @return string A viewable list of entities - */ - function list_entities_location($location, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) { - return list_entities_from_metadata('location', $location, $type, $subtype, $owner_guid, $limit, $fullview, $viewtypetoggle, $navigation); + + // Add the calendar stuff + $loc_join = " + JOIN {$CONFIG->dbprefix}metadata loc_start on e.guid=loc_start.entity_guid + JOIN {$CONFIG->dbprefix}metastrings loc_start_name on loc_start.name_id=loc_start_name.id + JOIN {$CONFIG->dbprefix}metastrings loc_start_value on loc_start.value_id=loc_start_value.id + + JOIN {$CONFIG->dbprefix}metadata loc_end on e.guid=loc_end.entity_guid + JOIN {$CONFIG->dbprefix}metastrings loc_end_name on loc_end.name_id=loc_end_name.id + JOIN {$CONFIG->dbprefix}metastrings loc_end_value on loc_end.value_id=loc_end_value.id + "; + + $lat_min = $lat - $radius; + $lat_max = $lat + $radius; + $long_min = $long - $radius; + $long_max = $long + $radius; + + $where[] = "loc_start_name.string='geo:lat'"; + $where[] = "loc_start_value.string>=$lat_min"; + $where[] = "loc_start_value.string<=$lat_max"; + $where[] = "loc_end_name.string='geo:long'"; + $where[] = "loc_end_value.string >= $long_min"; + $where[] = "loc_end_value.string <= $long_max"; + + if (!$count) { + $query = "SELECT e.* from {$CONFIG->dbprefix}entities e $loc_join where "; + } else { + $query = "SELECT count(e.guid) as total from {$CONFIG->dbprefix}entities e $loc_join where "; + } + foreach ($where as $w) { + $query .= " $w and "; } - - /** - * List items within a given geographic area. - * - * @param real $lat Latitude - * @param real $long Longitude - * @param real $radius The radius - * @param string $type The type of entity (eg "user", "object" etc) - * @param string $subtype The arbitrary subtype of the entity - * @param int $owner_guid The GUID of the owning user - * @param int $limit The number of entities to display per page (default: 10) - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow gallery view - * @param true|false $pagination Display pagination? Default: true - * @return string A viewable list of entities - */ - function list_entities_in_area($lat, $long, $radius, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) { - - $offset = (int) get_input('offset'); - $count = get_entities_in_area($lat, $long, $radius, $type, $subtype, $owner_guid, "", $limit, $offset, true); - $entities = get_entities_in_area($lat, $long, $radius, $type, $subtype, $owner_guid, "", $limit, $offset); - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $navigation); + $query .= get_access_sql_suffix('e'); // Add access controls + + if (!$count) { + $query .= " order by n.calendar_start $order_by"; + // Add order and limit + if ($limit) { + $query .= " limit $offset, $limit"; + } + $dt = get_data($query, "entity_row_to_elggstar"); + return $dt; + } else { + $total = get_data_row($query); + return $total->total; } - - // Some distances in degrees (approximate) - define("MILE", 0.01515); - define("KILOMETER", 0.00932); - - - // TODO: get objects within x miles by entities, metadata and relationship - - // TODO: List - - -?> \ No newline at end of file +} + +/** + * List entities in a given location + * + * @param string $location Location + * @param string $type The type of entity (eg "user", "object" etc) + * @param string $subtype The arbitrary subtype of the entity + * @param int $owner_guid The GUID of the owning user + * @param int $limit The number of entities to display per page (default: 10) + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow gallery view + * @param true|false $pagination Display pagination? Default: true + * @return string A viewable list of entities + */ +function list_entities_location($location, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) { + return list_entities_from_metadata('location', $location, $type, $subtype, $owner_guid, $limit, $fullview, $viewtypetoggle, $navigation); +} + +/** + * List items within a given geographic area. + * + * @param real $lat Latitude + * @param real $long Longitude + * @param real $radius The radius + * @param string $type The type of entity (eg "user", "object" etc) + * @param string $subtype The arbitrary subtype of the entity + * @param int $owner_guid The GUID of the owning user + * @param int $limit The number of entities to display per page (default: 10) + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow gallery view + * @param true|false $pagination Display pagination? Default: true + * @return string A viewable list of entities + */ +function list_entities_in_area($lat, $long, $radius, $type= "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $navigation = true) { + + $offset = (int) get_input('offset'); + $count = get_entities_in_area($lat, $long, $radius, $type, $subtype, $owner_guid, "", $limit, $offset, true); + $entities = get_entities_in_area($lat, $long, $radius, $type, $subtype, $owner_guid, "", $limit, $offset); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $navigation); +} + +// Some distances in degrees (approximate) +define("MILE", 0.01515); +define("KILOMETER", 0.00932); + +// TODO: get objects within x miles by entities, metadata and relationship + +// TODO: List \ No newline at end of file diff --git a/engine/lib/mb_wrapper.php b/engine/lib/mb_wrapper.php index 6221f4aa1..2cef15c64 100644 --- a/engine/lib/mb_wrapper.php +++ b/engine/lib/mb_wrapper.php @@ -1,62 +1,61 @@ \ No newline at end of file + + return substr($string, $start, $length); +} + +// TODO: Other wrapper functions \ No newline at end of file diff --git a/engine/lib/memcache.php b/engine/lib/memcache.php index 5f65ce9a7..498d1ff4f 100644 --- a/engine/lib/memcache.php +++ b/engine/lib/memcache.php @@ -1,198 +1,192 @@ + * @link http://elgg.org/ + */ + +/** + * Memcache wrapper class. + * @author Curverider Ltd + */ +class ElggMemcache extends ElggSharedMemoryCache { + /** + * Minimum version of memcached needed to run + * + */ + private static $MINSERVERVERSION = '1.1.12'; + /** - * Elgg memcache support. - * - * Requires php5-memcache to work. - * - * @package Elgg - * @subpackage API - * @author Curverider Ltd - * @link http://elgg.org/ + * Memcache object */ + private $memcache; /** - * Memcache wrapper class. - * @author Curverider Ltd + * Expiry of saved items (default timeout after a day to prevent anything getting too stale) */ - class ElggMemcache extends ElggSharedMemoryCache - { - /** - * Minimum version of memcached needed to run - * - */ - private static $MINSERVERVERSION = '1.1.12'; - - /** - * Memcache object - */ - private $memcache; - - /** - * Expiry of saved items (default timeout after a day to prevent anything getting too stale) - */ - private $expires = 86400; - - /** - * The version of memcache running - */ - private $version = 0; - - /** - * Connect to memcache. - * - * @param string $cache_id The namespace for this cache to write to - note, namespaces of the same name are shared! - */ - function __construct($namespace = 'default') - { - global $CONFIG; - - $this->setNamespace($namespace); - - // Do we have memcache? - if (!class_exists('Memcache')) - throw new ConfigurationException(elgg_echo('memcache:notinstalled')); - - // Create memcache object - $this->memcache = new Memcache; - - // Now add servers - if (!$CONFIG->memcache_servers) - throw new ConfigurationException(elgg_echo('memcache:noservers')); - - if (is_callable($this->memcache, 'addServer')) - { - foreach ($CONFIG->memcache_servers as $server) - { - if (is_array($server)) - { - $this->memcache->addServer( - $server[0], - isset($server[1]) ? $server[1] : 11211, - isset($server[2]) ? $server[2] : true, - isset($server[3]) ? $server[3] : null, - isset($server[4]) ? $server[4] : 1, - isset($server[5]) ? $server[5] : 15, - isset($server[6]) ? $server[6] : true - ); - - } - else - $this->memcache->addServer($server, 11211); + private $expires = 86400; + + /** + * The version of memcache running + */ + private $version = 0; + + /** + * Connect to memcache. + * + * @param string $cache_id The namespace for this cache to write to - note, namespaces of the same name are shared! + */ + function __construct($namespace = 'default') { + global $CONFIG; + + $this->setNamespace($namespace); + + // Do we have memcache? + if (!class_exists('Memcache')) { + throw new ConfigurationException(elgg_echo('memcache:notinstalled')); + } + + // Create memcache object + $this->memcache = new Memcache; + + // Now add servers + if (!$CONFIG->memcache_servers) { + throw new ConfigurationException(elgg_echo('memcache:noservers')); + } + + if (is_callable($this->memcache, 'addServer')) { + foreach ($CONFIG->memcache_servers as $server) { + if (is_array($server)) { + $this->memcache->addServer( + $server[0], + isset($server[1]) ? $server[1] : 11211, + isset($server[2]) ? $server[2] : true, + isset($server[3]) ? $server[3] : null, + isset($server[4]) ? $server[4] : 1, + isset($server[5]) ? $server[5] : 15, + isset($server[6]) ? $server[6] : true + ); + + } else { + $this->memcache->addServer($server, 11211); } } - else - { - if ((isset($CONFIG->debug)) && ($CONFIG->debug == true)) - error_log(elgg_echo('memcache:noaddserver')); - - $server = $CONFIG->memcache_servers[0]; - if (is_array($server)) - { - $this->memcache->connect($server[0], $server[1]); - } - else - $this->memcache->addServer($server, 11211); + } else { + if ((isset($CONFIG->debug)) && ($CONFIG->debug == true)) { + error_log(elgg_echo('memcache:noaddserver')); + } + + $server = $CONFIG->memcache_servers[0]; + if (is_array($server)) { + $this->memcache->connect($server[0], $server[1]); + } else { + $this->memcache->addServer($server, 11211); } - - // Get version - $this->version = $this->memcache->getversion(); - if (version_compare($this->version, ElggMemcache::$MINSERVERVERSION, '<')) - throw new ConfigurationException(sprintf(elgg_echo('memcache:versiontoolow'), ElggMemcache::$MINSERVERVERSION, $this->version)); - - // Set some defaults - if (isset($CONFIG->memcache_expires)) - $this->expires = $CONFIG->memcache_expires; - - } - - /** - * Set the default expiry. - * - * @param int $expires The lifetime as a unix timestamp or time from now. Defaults forever. - */ - public function setDefaultExpiry($expires = 0) - { - $this->expires = $expires; - } - - /** - * Combine a key with the namespace. - * Memcache can only accept <250 char key. If the given key is too long it is shortened. - * - * @param string $key The key - * @return string The new key. - */ - private function make_memcache_key($key) - { - $prefix = $this->getNamespace() . ":"; - - if (strlen($prefix.$key)> 250) - $key = md5($key); - - return $prefix.$key; - } - - public function save($key, $data) - { - $key = $this->make_memcache_key($key); - - $result = $this->memcache->set($key, $data, null, $this->expires); - if ((isset($CONFIG->debug)) && ($CONFIG->debug == true) && (!$result)) - error_log("MEMCACHE: FAILED TO SAVE $key"); - - return $result; - } - - public function load($key, $offset = 0, $limit = null) - { - $key = $this->make_memcache_key($key); - - $result = $this->memcache->get($key); - if ((isset($CONFIG->debug)) && ($CONFIG->debug == true) && (!$result)) - error_log("MEMCACHE: FAILED TO LOAD $key"); - - return $result; } - - public function delete($key) - { - $key = $this->make_memcache_key($key); - - return $this->memcache->delete($key, 0); + + // Get version + $this->version = $this->memcache->getversion(); + if (version_compare($this->version, ElggMemcache::$MINSERVERVERSION, '<')) { + throw new ConfigurationException(sprintf(elgg_echo('memcache:versiontoolow'), ElggMemcache::$MINSERVERVERSION, $this->version)); } - - public function clear() - { - // DISABLE clearing for now - you must use delete on a specific key. - return true; - - //TODO: Namespaces as in #532 + + // Set some defaults + if (isset($CONFIG->memcache_expires)) { + $this->expires = $CONFIG->memcache_expires; } - } - + /** - * Return true if memcache is available and configured. + * Set the default expiry. * - * @return bool + * @param int $expires The lifetime as a unix timestamp or time from now. Defaults forever. */ - function is_memcache_available() - { - global $CONFIG; - - static $memcache_available; - - if ((!isset($CONFIG->memcache)) || (!$CONFIG->memcache)) - return false; - - if (($memcache_available!==true) && ($memcache_available!==false)) // If we haven't set variable to something - { - try { - $tmp = new ElggMemcache(); - $memcache_available = true; // No exception thrown so we have memcache available - } catch (Exception $e) { $memcache_available = false; } + public function setDefaultExpiry($expires = 0) { + $this->expires = $expires; + } + + /** + * Combine a key with the namespace. + * Memcache can only accept <250 char key. If the given key is too long it is shortened. + * + * @param string $key The key + * @return string The new key. + */ + private function make_memcache_key($key) { + $prefix = $this->getNamespace() . ":"; + + if (strlen($prefix.$key)> 250) { + $key = md5($key); + } + + return $prefix.$key; + } + + public function save($key, $data) { + $key = $this->make_memcache_key($key); + + $result = $this->memcache->set($key, $data, null, $this->expires); + if ((isset($CONFIG->debug)) && ($CONFIG->debug == true) && (!$result)) { + error_log("MEMCACHE: FAILED TO SAVE $key"); + } + + return $result; + } + + public function load($key, $offset = 0, $limit = null) { + $key = $this->make_memcache_key($key); + + $result = $this->memcache->get($key); + if ((isset($CONFIG->debug)) && ($CONFIG->debug == true) && (!$result)) { + error_log("MEMCACHE: FAILED TO LOAD $key"); + } + + return $result; + } + + public function delete($key) { + $key = $this->make_memcache_key($key); + + return $this->memcache->delete($key, 0); + } + + public function clear() { + // DISABLE clearing for now - you must use delete on a specific key. + return true; + + //TODO: Namespaces as in #532 + } +} + +/** + * Return true if memcache is available and configured. + * + * @return bool + */ +function is_memcache_available() { + global $CONFIG; + + static $memcache_available; + + if ((!isset($CONFIG->memcache)) || (!$CONFIG->memcache)) { + return false; + } + + // If we haven't set variable to something + if (($memcache_available!==true) && ($memcache_available!==false)) { + try { + $tmp = new ElggMemcache(); + // No exception thrown so we have memcache available + $memcache_available = true; + } catch (Exception $e) { + $memcache_available = false; } - - return $memcache_available; } -?> \ No newline at end of file + + return $memcache_available; +} \ No newline at end of file diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php index c6e5db4cd..5ca39b586 100644 --- a/engine/lib/metadata.php +++ b/engine/lib/metadata.php @@ -1,912 +1,975 @@ - - * @link http://elgg.org/ - */ +/** + * Elgg metadata + * Functions to manage object metadata. + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + */ +/** + * ElggMetadata + * This class describes metadata that can be attached to ElggEntities. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Core + */ +class ElggMetadata extends ElggExtender { /** - * ElggMetadata - * This class describes metadata that can be attached to ElggEntities. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Core + * Construct a new site object, optionally from a given id value or row. + * + * @param mixed $id */ - class ElggMetadata extends ElggExtender - { - - /** - * Construct a new site object, optionally from a given id value or row. - * - * @param mixed $id - */ - function __construct($id = null) - { - $this->attributes = array(); - - if (!empty($id)) { - - if ($id instanceof stdClass) - $metadata = $id; // Create from db row - else - $metadata = get_metadata($id); - - if ($metadata) { - $objarray = (array) $metadata; - foreach($objarray as $key => $value) { - $this->attributes[$key] = $value; - } - $this->attributes['type'] = "metadata"; - } - } - } - - /** - * Class member get overloading - * - * @param string $name - * @return mixed - */ - function __get($name) { - return $this->get($name); - } - - /** - * Class member set overloading - * - * @param string $name - * @param mixed $value - * @return mixed - */ - function __set($name, $value) { - return $this->set($name, $value); - } + function __construct($id = null) { + $this->attributes = array(); - /** - * Determines whether or not the user can edit this piece of metadata - * - * @return true|false Depending on permissions - */ - function canEdit() { - - if ($entity = get_entity($this->get('entity_guid'))) { - return $entity->canEditMetadata($this); + if (!empty($id)) { + // Create from db row + if ($id instanceof stdClass) { + $metadata = $id; + } else { + $metadata = get_metadata($id); } - return false; - - } - - /** - * Save matadata object - * - * @return int the metadata object id - */ - function save() - { - if ($this->id > 0) - return update_metadata($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id); - else - { - $this->id = create_metadata($this->entity_guid, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id); - if (!$this->id) throw new IOException(sprintf(elgg_new('IOException:UnableToSaveNew'), get_class())); - return $this->id; + + if ($metadata) { + $objarray = (array) $metadata; + foreach($objarray as $key => $value) { + $this->attributes[$key] = $value; + } + $this->attributes['type'] = "metadata"; } - } - - /** - * Delete a given metadata. - */ - function delete() - { - return delete_metadata($this->id); - } - - /** - * Get a url for this item of metadata. - * - * @return string - */ - public function getURL() { return get_metadata_url($this->id); } - - // SYSTEM LOG INTERFACE //////////////////////////////////////////////////////////// - - /** - * For a given ID, return the object associated with it. - * This is used by the river functionality primarily. - * This is useful for checking access permissions etc on objects. - */ - public function getObjectFromID($id) { return get_metadata($id); } } /** - * Convert a database row to a new ElggMetadata + * Class member get overloading * - * @param stdClass $row - * @return stdClass or ElggMetadata + * @param string $name + * @return mixed */ - function row_to_elggmetadata($row) - { - if (!($row instanceof stdClass)) - return $row; - - return new ElggMetadata($row); + function __get($name) { + return $this->get($name); } - /** - * Get a specific item of metadata. - * - * @param $id int The item of metadata being retrieved. + * Class member set overloading + * + * @param string $name + * @param mixed $value + * @return mixed */ - function get_metadata($id) - { - global $CONFIG; - - $id = (int)$id; - $access = get_access_sql_suffix("e"); - $md_access = get_access_sql_suffix("m"); - - return row_to_elggmetadata(get_data_row("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e on e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.id=$id and $access and $md_access")); + function __set($name, $value) { + return $this->set($name, $value); } - + /** - * Removes metadata on an entity with a particular name, optionally with a given value. + * Determines whether or not the user can edit this piece of metadata * - * @param int $entity_guid The entity GUID - * @param string $name The name of the metadata - * @param string $value The optional value of the item (useful for removing a single item in a multiple set) - * @return true|false Depending on success + * @return true|false Depending on permissions */ - function remove_metadata($entity_guid, $name, $value = "") { - - global $CONFIG; - $entity_guid = (int) $entity_guid; - $name = sanitise_string($name); - $value = sanitise_string($value); - - $query = "SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name); - if ($value!="") - $query .= " and value_id=" . add_metastring($value); - - if ($existing = get_data($query)) { - foreach($existing as $ex) - delete_metadata($ex->id); - return true; + function canEdit() { + if ($entity = get_entity($this->get('entity_guid'))) { + return $entity->canEditMetadata($this); } return false; - } - + /** - * Create a new metadata object, or update an existing one. + * Save matadata object * - * @param int $entity_guid - * @param string $name - * @param string $value - * @param string $value_type - * @param int $owner_guid - * @param int $access_id - * @param bool $allow_multiple + * @return int the metadata object id */ - function create_metadata($entity_guid, $name, $value, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false) - { - global $CONFIG; - - $entity_guid = (int)$entity_guid; - //$name = sanitise_string(trim($name)); - //$value = sanitise_string(trim($value)); - $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type))); - $time = time(); - $owner_guid = (int)$owner_guid; - $allow_multiple = (boolean)$allow_multiple; - - if ($owner_guid==0) $owner_guid = get_loggedin_userid(); - - $access_id = (int)$access_id; - - $id = false; - - $existing = get_data_row("SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name) . " limit 1"); - if (($existing) && (!$allow_multiple) && (isset($value))) - { - $id = $existing->id; - $result = update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id); - - if (!$result) return false; - } - else if (isset($value)) - { - // Support boolean types - if (is_bool($value)) { - if ($value) - $value = 1; - else - $value = 0; - } - - // Add the metastrings - $value = add_metastring($value); - if (!$value) return false; - - $name = add_metastring($name); - if (!$name) return false; - - // If ok then add it - $id = insert_data("INSERT into {$CONFIG->dbprefix}metadata (entity_guid, name_id, value_id, value_type, owner_guid, time_created, access_id) VALUES ($entity_guid, '$name','$value','$value_type', $owner_guid, $time, $access_id)"); - - if ($id!==false) { - $obj = get_metadata($id); - if (trigger_elgg_event('create', 'metadata', $obj)) { - return true; - } else { - delete_metadata($id); - } + function save() { + if ($this->id > 0) { + return update_metadata($this->id, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id); + } else { + $this->id = create_metadata($this->entity_guid, $this->name, $this->value, $this->value_type, $this->owner_guid, $this->access_id); + if (!$this->id) { + throw new IOException(sprintf(elgg_new('IOException:UnableToSaveNew'), get_class())); } - - } else if ($existing) { -// TODO: Check... are you sure you meant to do this Ben? :) - $id = $existing->id; - delete_metadata($id); - + return $this->id; } - - return $id; } - + + /** + * Delete a given metadata. + */ + function delete() { + return delete_metadata($this->id); + } + /** - * Update an item of metadata. + * Get a url for this item of metadata. * - * @param int $id - * @param string $name - * @param string $value - * @param string $value_type - * @param int $owner_guid - * @param int $access_id + * @return string */ - function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id) - { - global $CONFIG; + public function getURL() { + return get_metadata_url($this->id); + } - $id = (int)$id; + // SYSTEM LOG INTERFACE //////////////////////////////////////////////////////////// - if (!$md = get_metadata($id)) return false; - if (!$md->canEdit()) return false; + /** + * For a given ID, return the object associated with it. + * This is used by the river functionality primarily. + * This is useful for checking access permissions etc on objects. + */ + public function getObjectFromID($id) { + return get_metadata($id); + } +} - // If memcached then we invalidate the cache for this entry - static $metabyname_memcache; - if ((!$metabyname_memcache) && (is_memcache_available())) - $metabyname_memcache = new ElggMemcache('metabyname_memcache'); - if ($metabyname_memcache) $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); - - //$name = sanitise_string(trim($name)); - //$value = sanitise_string(trim($value)); - $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type))); - - $owner_guid = (int)$owner_guid; - if ($owner_guid==0) $owner_guid = get_loggedin_userid(); - - $access_id = (int)$access_id; - - $access = get_access_sql_suffix(); - - // Support boolean types (as integers) +/** + * Convert a database row to a new ElggMetadata + * + * @param stdClass $row + * @return stdClass or ElggMetadata + */ +function row_to_elggmetadata($row) { + if (!($row instanceof stdClass)) { + return $row; + } + + return new ElggMetadata($row); +} + +/** + * Get a specific item of metadata. + * + * @param $id int The item of metadata being retrieved. + */ +function get_metadata($id) { + global $CONFIG; + + $id = (int)$id; + $access = get_access_sql_suffix("e"); + $md_access = get_access_sql_suffix("m"); + + return row_to_elggmetadata(get_data_row("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e on e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.id=$id and $access and $md_access")); +} + +/** + * Removes metadata on an entity with a particular name, optionally with a given value. + * + * @param int $entity_guid The entity GUID + * @param string $name The name of the metadata + * @param string $value The optional value of the item (useful for removing a single item in a multiple set) + * @return true|false Depending on success + */ +function remove_metadata($entity_guid, $name, $value = "") { + global $CONFIG; + $entity_guid = (int) $entity_guid; + $name = sanitise_string($name); + $value = sanitise_string($value); + + $query = "SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name); + if ($value!="") { + $query .= " and value_id=" . add_metastring($value); + } + + if ($existing = get_data($query)) { + foreach($existing as $ex) { + delete_metadata($ex->id); + } + return true; + } + + return false; +} + +/** + * Create a new metadata object, or update an existing one. + * + * @param int $entity_guid + * @param string $name + * @param string $value + * @param string $value_type + * @param int $owner_guid + * @param int $access_id + * @param bool $allow_multiple + */ +function create_metadata($entity_guid, $name, $value, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false) { + global $CONFIG; + + $entity_guid = (int)$entity_guid; + //$name = sanitise_string(trim($name)); + //$value = sanitise_string(trim($value)); + $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type))); + $time = time(); + $owner_guid = (int)$owner_guid; + $allow_multiple = (boolean)$allow_multiple; + + if ($owner_guid==0) { + $owner_guid = get_loggedin_userid(); + } + + $access_id = (int)$access_id; + + $id = false; + + $existing = get_data_row("SELECT * from {$CONFIG->dbprefix}metadata WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name) . " limit 1"); + if (($existing) && (!$allow_multiple) && (isset($value))) { + $id = $existing->id; + $result = update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id); + + if (!$result) { + return false; + } + } + else if (isset($value)) { + // Support boolean types if (is_bool($value)) { - if ($value) + if ($value) { $value = 1; - else + } else { $value = 0; + } } - - // Add the metastring + + // Add the metastrings $value = add_metastring($value); - if (!$value) return false; - + if (!$value) { + return false; + } + $name = add_metastring($name); - if (!$name) return false; + if (!$name) { + return false; + } + + // If ok then add it + $id = insert_data("INSERT into {$CONFIG->dbprefix}metadata (entity_guid, name_id, value_id, value_type, owner_guid, time_created, access_id) VALUES ($entity_guid, '$name','$value','$value_type', $owner_guid, $time, $access_id)"); - // If ok then add it - $result = update_data("UPDATE {$CONFIG->dbprefix}metadata set value_id='$value', value_type='$value_type', access_id=$access_id, owner_guid=$owner_guid where id=$id and name_id='$name'"); - if ($result!==false) { + if ($id!==false) { $obj = get_metadata($id); - if (trigger_elgg_event('update', 'metadata', $obj)) { + if (trigger_elgg_event('create', 'metadata', $obj)) { return true; } else { delete_metadata($id); } } - - return $result; + + } else if ($existing) { + // TODO: Check... are you sure you meant to do this Ben? :) + $id = $existing->id; + delete_metadata($id); } - - /** - * This function creates metadata from an associative array of "key => value" pairs. - * - * @param int $entity_guid - * @param string $name_and_values - * @param string $value_type - * @param int $owner_guid - * @param int $access_id - * @param bool $allow_multiple - */ - function create_metadata_from_array($entity_guid, array $name_and_values, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false) - { - foreach ($name_and_values as $k => $v) - if (!create_metadata($entity_guid, $k, $v, $value_type, $owner_guid, $access_id, $allow_multiple)) return false; - - return true; + + return $id; +} + +/** + * Update an item of metadata. + * + * @param int $id + * @param string $name + * @param string $value + * @param string $value_type + * @param int $owner_guid + * @param int $access_id + */ +function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id) { + global $CONFIG; + + $id = (int)$id; + + if (!$md = get_metadata($id)) { + return false; } - - /** - * Delete an item of metadata, where the current user has access. - * - * @param $id int The item of metadata to delete. - */ - function delete_metadata($id) - { - global $CONFIG; - - $id = (int)$id; - $metadata = get_metadata($id); - - if ($metadata) { - // Tidy up if memcache is enabled. - static $metabyname_memcache; - if ((!$metabyname_memcache) && (is_memcache_available())) - $metabyname_memcache = new ElggMemcache('metabyname_memcache'); - if ($metabyname_memcache) $metabyname_memcache->delete("{$metadata->entity_guid}:{$metadata->name_id}"); - - if (($metadata->canEdit()) && (trigger_elgg_event('delete', 'metadata', $metadata))) - return delete_data("DELETE from {$CONFIG->dbprefix}metadata where id=$id"); - } - + if (!$md->canEdit()) { return false; } - - /** - * Return the metadata values that match your query. - * - * @param string $meta_name - * @return mixed either a value, an array of ElggMetadata or false. - */ - function get_metadata_byname($entity_guid, $meta_name) - { - global $CONFIG; - - $meta_name = get_metastring_id($meta_name); - - if (empty($meta_name)) return false; - - $entity_guid = (int)$entity_guid; - $access = get_access_sql_suffix("e"); - $md_access = get_access_sql_suffix("m"); - - // If memcache is available then cache this (cache only by name for now since this is the most common query) - $meta = null; - static $metabyname_memcache; - if ((!$metabyname_memcache) && (is_memcache_available())) - $metabyname_memcache = new ElggMemcache('metabyname_memcache'); - if ($metabyname_memcache) $meta = $metabyname_memcache->load("{$entity_guid}:{$meta_name}"); - if ($meta) return $meta; - $result = get_data("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.entity_guid=$entity_guid and m.name_id='$meta_name' and $access and $md_access", "row_to_elggmetadata"); - if (!$result) - return false; - - // Cache if memcache available - if ($metabyname_memcache) - { - if (count($result) == 1) $r = $result[0]; else $r = $result; - $metabyname_memcache->setDefaultExpiry(3600); // This is a bit of a hack - we shorten the expiry on object metadata so that it'll be gone in an hour. This means that deletions and more importantly updates will filter through eventually. - $metabyname_memcache->save("{$entity_guid}:{$meta_name}", $r); - - } - if (count($result) == 1) - return $result[0]; - - return $result; + // If memcached then we invalidate the cache for this entry + static $metabyname_memcache; + if ((!$metabyname_memcache) && (is_memcache_available())) { + $metabyname_memcache = new ElggMemcache('metabyname_memcache'); } - - /** - * Return all the metadata for a given GUID. - * - * @param int $entity_guid - */ - function get_metadata_for_entity($entity_guid) - { - global $CONFIG; - - $entity_guid = (int)$entity_guid; - $access = get_access_sql_suffix("e"); - $md_access = get_access_sql_suffix("m"); - - return get_data("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.entity_guid=$entity_guid and $access and $md_access", "row_to_elggmetadata"); + + if ($metabyname_memcache) { + $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); } - /** - * Get the metadata where the entities they are referring to match a given criteria. - * - * @param mixed $meta_name - * @param mixed $meta_value - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity. - * @param int $limit - * @param int $offset - * @param string $order_by Optional ordering. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - */ - function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $entity_subtype = "", $limit = 10, $offset = 0, $order_by = "", $site_guid = 0) - { - global $CONFIG; - - $meta_n = get_metastring_id($meta_name); - $meta_v = get_metastring_id($meta_value); - - $entity_type = sanitise_string($entity_type); - $entity_subtype = get_subtype_id($entity_type, $entity_subtype); - $limit = (int)$limit; - $offset = (int)$offset; - if ($order_by == "") $order_by = "e.time_created desc"; - $order_by = sanitise_string($order_by); - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - - $where = array(); - - if ($entity_type!="") - $where[] = "e.type='$entity_type'"; - if ($entity_subtype) - $where[] = "e.subtype=$entity_subtype"; - if ($meta_name!="") { - if (!$meta_v) return false; // The value is set, but we didn't get a value... so something went wrong. - $where[] = "m.name_id='$meta_n'"; - } - if ($meta_value!="") { - if (!$meta_v) return false; // The value is set, but we didn't get a value... so something went wrong. - $where[] = "m.value_id='$meta_v'"; - } - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - - $query = "SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where"; - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + //$name = sanitise_string(trim($name)); + //$value = sanitise_string(trim($value)); + $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type))); - return get_data($query, "row_to_elggmetadata"); + $owner_guid = (int)$owner_guid; + if ($owner_guid==0) { + $owner_guid = get_loggedin_userid(); } - - /** - * Return a list of entities based on the given search criteria. - * - * @param mixed $meta_name - * @param mixed $meta_value - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity. - * @param int $limit - * @param int $offset - * @param string $order_by Optional ordering. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) - * - * @return int|array A list of entities, or a count if $count is set to true - */ - function get_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) - { - global $CONFIG; - - $meta_n = get_metastring_id($meta_name); - $meta_v = get_metastring_id($meta_value); - - $entity_type = sanitise_string($entity_type); - $entity_subtype = get_subtype_id($entity_type, $entity_subtype); - $limit = (int)$limit; - $offset = (int)$offset; - if ($order_by == "") - $order_by = "e.time_created desc"; - else - $order_by = "e.time_created, {$order_by}"; - $order_by = sanitise_string($order_by); - $site_guid = (int) $site_guid; - if ((is_array($owner_guid) && (count($owner_guid)))) { - foreach($owner_guid as $key => $guid) { - $owner_guid[$key] = (int) $guid; - } - } else { - $owner_guid = (int) $owner_guid; - } - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - //$access = get_access_list(); - - $where = array(); - - if ($entity_type!=="") - $where[] = "e.type='$entity_type'"; - if ($entity_subtype) - $where[] = "e.subtype=$entity_subtype"; - if ($meta_name!=="") - $where[] = "m.name_id='$meta_n'"; - if ($meta_value!=="") - $where[] = "m.value_id='$meta_v'"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - if (is_array($owner_guid)) { - $where[] = "e.container_guid in (".implode(",",$owner_guid).")"; - } else if ($owner_guid > 0) - $where[] = "e.container_guid = {$owner_guid}"; - - if (!$count) { - $query = "SELECT distinct e.* "; - } else { - $query = "SELECT count(distinct e.guid) as total "; - } - - $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid where"; - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); + + $access_id = (int)$access_id; + + $access = get_access_sql_suffix(); + + // Support boolean types (as integers) + if (is_bool($value)) { + if ($value) { + $value = 1; } else { - if ($row = get_data_row($query)) - return $row->total; + $value = 0; } + } + + // Add the metastring + $value = add_metastring($value); + if (!$value) { return false; } - - /** - * Return a list of entities suitable for display based on the given search criteria. - * - * @see elgg_view_entity_list - * - * @param mixed $meta_name Metadata name to search on - * @param mixed $meta_value The value to match, optionally - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity - * @param int $limit Number of entities to display per page - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow users to toggle to the gallery view. Default: true - * @param true|false $pagination Display pagination? Default: true - * - * @return string A list of entities suitable for display - */ - function list_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) { - - $offset = (int) get_input('offset'); - $limit = (int) $limit; - $count = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, true); - $entities = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, false); - - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); - + + $name = add_metastring($name); + if (!$name) { + return false; } - /** - * Returns a list of entities based on the given search criteria. - * - * @param array $meta_array Array of 'name' => 'value' pairs - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity. - * @param int $limit - * @param int $offset - * @param string $order_by Optional ordering. - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) - * @param string $meta_array_operator Operator used for joining the metadata array together - * @return int|array List of ElggEntities, or the total number if count is set to false - */ - function get_entities_from_metadata_multi($meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false, $meta_array_operator = 'and') - { - global $CONFIG; - - if (!is_array($meta_array) || sizeof($meta_array) == 0) { + // If ok then add it + $result = update_data("UPDATE {$CONFIG->dbprefix}metadata set value_id='$value', value_type='$value_type', access_id=$access_id, owner_guid=$owner_guid where id=$id and name_id='$name'"); + if ($result!==false) { + $obj = get_metadata($id); + if (trigger_elgg_event('update', 'metadata', $obj)) { + return true; + } else { + delete_metadata($id); + } + } + + return $result; +} + +/** + * This function creates metadata from an associative array of "key => value" pairs. + * + * @param int $entity_guid + * @param string $name_and_values + * @param string $value_type + * @param int $owner_guid + * @param int $access_id + * @param bool $allow_multiple + */ +function create_metadata_from_array($entity_guid, array $name_and_values, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false) { + foreach ($name_and_values as $k => $v) { + if (!create_metadata($entity_guid, $k, $v, $value_type, $owner_guid, $access_id, $allow_multiple)) { return false; } - - $where = array(); - - $mindex = 1; - $join = ""; - $metawhere = array(); - $meta_array_operator = sanitise_string($meta_array_operator); - foreach($meta_array as $meta_name => $meta_value) { - $meta_n = get_metastring_id($meta_name); - $meta_v = get_metastring_id($meta_value); - $join .= " JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid "; - /*if ($meta_name!=="") - $where[] = "m{$mindex}.name_id='$meta_n'"; - if ($meta_value!=="") - $where[] = "m{$mindex}.value_id='$meta_v'";*/ - $metawhere[] = "(m{$mindex}.name_id='$meta_n' AND m{$mindex}.value_id='$meta_v')"; - $mindex++; + } + return true; +} + +/** + * Delete an item of metadata, where the current user has access. + * + * @param $id int The item of metadata to delete. + */ +function delete_metadata($id) { + global $CONFIG; + + $id = (int)$id; + $metadata = get_metadata($id); + + if ($metadata) { + // Tidy up if memcache is enabled. + static $metabyname_memcache; + if ((!$metabyname_memcache) && (is_memcache_available())) { + $metabyname_memcache = new ElggMemcache('metabyname_memcache'); } - $where[] = "(".implode($meta_array_operator, $metawhere).")"; - - $entity_type = sanitise_string($entity_type); - $entity_subtype = get_subtype_id($entity_type, $entity_subtype); - $limit = (int)$limit; - $offset = (int)$offset; - if ($order_by == "") $order_by = "e.time_created desc"; - $order_by = sanitise_string($order_by); - if ((is_array($owner_guid) && (count($owner_guid)))) { - foreach($owner_guid as $key => $guid) { - $owner_guid[$key] = (int) $guid; - } - } else { - $owner_guid = (int) $owner_guid; + + if ($metabyname_memcache) { + $metabyname_memcache->delete("{$metadata->entity_guid}:{$metadata->name_id}"); } - - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - //$access = get_access_list(); - - if ($entity_type!="") - $where[] = "e.type = '{$entity_type}'"; - if ($entity_subtype) - $where[] = "e.subtype = {$entity_subtype}"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - if (is_array($owner_guid)) { - $where[] = "e.container_guid in (".implode(",",$owner_guid).")"; - } else if ($owner_guid > 0) - $where[] = "e.container_guid = {$owner_guid}"; - //if ($owner_guid > 0) - // $where[] = "e.container_guid = {$owner_guid}"; - - if ($count) { - $query = "SELECT count(distinct e.guid) as total "; + + if (($metadata->canEdit()) && (trigger_elgg_event('delete', 'metadata', $metadata))) { + return delete_data("DELETE from {$CONFIG->dbprefix}metadata where id=$id"); + } + } + + return false; +} + +/** + * Return the metadata values that match your query. + * + * @param string $meta_name + * @return mixed either a value, an array of ElggMetadata or false. + */ +function get_metadata_byname($entity_guid, $meta_name) { + global $CONFIG; + + $meta_name = get_metastring_id($meta_name); + + if (empty($meta_name)) { + return false; + } + + $entity_guid = (int)$entity_guid; + $access = get_access_sql_suffix("e"); + $md_access = get_access_sql_suffix("m"); + + // If memcache is available then cache this (cache only by name for now since this is the most common query) + $meta = null; + static $metabyname_memcache; + if ((!$metabyname_memcache) && (is_memcache_available())) { + $metabyname_memcache = new ElggMemcache('metabyname_memcache'); + } + if ($metabyname_memcache) { + $meta = $metabyname_memcache->load("{$entity_guid}:{$meta_name}"); + } + if ($meta) { + return $meta; + } + + $result = get_data("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.entity_guid=$entity_guid and m.name_id='$meta_name' and $access and $md_access", "row_to_elggmetadata"); + if (!$result) { + return false; + } + + // Cache if memcache available + if ($metabyname_memcache) { + if (count($result) == 1) { + $r = $result[0]; } else { - $query = "SELECT distinct e.* "; + $r = $result; } - - $query .= " from {$CONFIG->dbprefix}entities e {$join} where"; - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - - $mindex = 1; - foreach($meta_array as $meta_name => $meta_value) { - $query .= ' and ' . get_access_sql_suffix("m{$mindex}"); // Add access controls - $mindex++; + // This is a bit of a hack - we shorten the expiry on object + // metadata so that it'll be gone in an hour. This means that + // deletions and more importantly updates will filter through eventually. + $metabyname_memcache->setDefaultExpiry(3600); + $metabyname_memcache->save("{$entity_guid}:{$meta_name}", $r); + } + if (count($result) == 1) { + return $result[0]; + } + + return $result; +} + +/** + * Return all the metadata for a given GUID. + * + * @param int $entity_guid + */ +function get_metadata_for_entity($entity_guid) { + global $CONFIG; + + $entity_guid = (int)$entity_guid; + $access = get_access_sql_suffix("e"); + $md_access = get_access_sql_suffix("m"); + + return get_data("SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}metadata m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where m.entity_guid=$entity_guid and $access and $md_access", "row_to_elggmetadata"); +} + +/** + * Get the metadata where the entities they are referring to match a given criteria. + * + * @param mixed $meta_name + * @param mixed $meta_value + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity. + * @param int $limit + * @param int $offset + * @param string $order_by Optional ordering. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + */ +function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $entity_subtype = "", $limit = 10, $offset = 0, $order_by = "", $site_guid = 0) { + global $CONFIG; + + $meta_n = get_metastring_id($meta_name); + $meta_v = get_metastring_id($meta_value); + + $entity_type = sanitise_string($entity_type); + $entity_subtype = get_subtype_id($entity_type, $entity_subtype); + $limit = (int)$limit; + $offset = (int)$offset; + if ($order_by == "") { + $order_by = "e.time_created desc"; + } + + $order_by = sanitise_string($order_by); + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + $where = array(); + + if ($entity_type!="") { + $where[] = "e.type='$entity_type'"; + } + + if ($entity_subtype) { + $where[] = "e.subtype=$entity_subtype"; + } + + if ($meta_name!="") { + if (!$meta_v) { + // The value is set, but we didn't get a value... so something went wrong. + return false; } - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); - } else { - if ($count = get_data_row($query)) { - return $count->total; - } + $where[] = "m.name_id='$meta_n'"; + } + if ($meta_value!="") { + // The value is set, but we didn't get a value... so something went wrong. + if (!$meta_v) { + return false; } - return false; + $where[] = "m.value_id='$meta_v'"; } - - /** - * Returns a viewable list of entities based on the given search criteria. - * - * @see elgg_view_entity_list - * - * @param array $meta_array Array of 'name' => 'value' pairs - * @param string $entity_type The type of entity to look for, eg 'site' or 'object' - * @param string $entity_subtype The subtype of the entity. - * @param int $limit - * @param int $offset - * @param string $order_by Optional ordering. - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow users to toggle to the gallery view. Default: true - * @param true|false $pagination Display pagination? Default: true - * @return string List of ElggEntities suitable for display - */ - function list_entities_from_metadata_multi($meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) { - - $offset = (int) get_input('offset'); - $limit = (int) $limit; - $count = get_entities_from_metadata_multi($meta_array, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", $site_guid, true); - $entities = get_entities_from_metadata_multi($meta_array, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", $site_guid, false); - - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); - - } - - /** - * Clear all the metadata for a given entity, assuming you have access to that metadata. - * - * @param int $guid - */ - function clear_metadata($entity_guid) - { - global $CONFIG; - - $entity_guid = (int)$entity_guid; - if ($entity = get_entity($entity_guid)) { - if ($entity->canEdit()) - return delete_data("DELETE from {$CONFIG->dbprefix}metadata where entity_guid={$entity_guid}"); + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + $query = "SELECT m.*, n.string as name, v.string as value from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid JOIN {$CONFIG->dbprefix}metastrings v on m.value_id = v.id JOIN {$CONFIG->dbprefix}metastrings n on m.name_id = n.id where"; + foreach ($where as $w) { + $query .= " $w and "; + } + $query .= get_access_sql_suffix("e"); // Add access controls + $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + + return get_data($query, "row_to_elggmetadata"); +} + +/** + * Return a list of entities based on the given search criteria. + * + * @param mixed $meta_name + * @param mixed $meta_value + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity. + * @param int $limit + * @param int $offset + * @param string $order_by Optional ordering. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) + * + * @return int|array A list of entities, or a count if $count is set to true + */ +function get_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) { + global $CONFIG; + + $meta_n = get_metastring_id($meta_name); + $meta_v = get_metastring_id($meta_value); + + $entity_type = sanitise_string($entity_type); + $entity_subtype = get_subtype_id($entity_type, $entity_subtype); + $limit = (int)$limit; + $offset = (int)$offset; + if ($order_by == "") { + $order_by = "e.time_created desc"; + } else { + $order_by = "e.time_created, {$order_by}"; + } + $order_by = sanitise_string($order_by); + $site_guid = (int) $site_guid; + if ((is_array($owner_guid) && (count($owner_guid)))) { + foreach($owner_guid as $key => $guid) { + $owner_guid[$key] = (int) $guid; } + } else { + $owner_guid = (int) $owner_guid; + } + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + //$access = get_access_list(); + + $where = array(); + + if ($entity_type!=="") { + $where[] = "e.type='$entity_type'"; + } + + if ($entity_subtype) { + $where[] = "e.subtype=$entity_subtype"; + } + if ($meta_name!=="") { + $where[] = "m.name_id='$meta_n'"; + } + if ($meta_value!=="") { + $where[] = "m.value_id='$meta_v'"; + } + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + if (is_array($owner_guid)) { + $where[] = "e.container_guid in (".implode(",",$owner_guid).")"; + } else if ($owner_guid > 0) { + $where[] = "e.container_guid = {$owner_guid}"; + } + + if (!$count) { + $query = "SELECT distinct e.* "; + } else { + $query = "SELECT count(distinct e.guid) as total "; + } + + $query .= "from {$CONFIG->dbprefix}entities e JOIN {$CONFIG->dbprefix}metadata m on e.guid = m.entity_guid where"; + foreach ($where as $w) { + $query .= " $w and "; + } + $query .= get_access_sql_suffix("e"); // Add access controls + $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls + + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($row = get_data_row($query)) { + return $row->total; + } + } + return false; +} + +/** + * Return a list of entities suitable for display based on the given search criteria. + * + * @see elgg_view_entity_list + * + * @param mixed $meta_name Metadata name to search on + * @param mixed $meta_value The value to match, optionally + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity + * @param int $limit Number of entities to display per page + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow users to toggle to the gallery view. Default: true + * @param true|false $pagination Display pagination? Default: true + * + * @return string A list of entities suitable for display + */ +function list_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) { + $offset = (int) get_input('offset'); + $limit = (int) $limit; + $count = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, true); + $entities = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, false); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); +} + +/** + * Returns a list of entities based on the given search criteria. + * + * @param array $meta_array Array of 'name' => 'value' pairs + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity. + * @param int $limit + * @param int $offset + * @param string $order_by Optional ordering. + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false) + * @param string $meta_array_operator Operator used for joining the metadata array together + * @return int|array List of ElggEntities, or the total number if count is set to false + */ +function get_entities_from_metadata_multi($meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false, $meta_array_operator = 'and') { + global $CONFIG; + + if (!is_array($meta_array) || sizeof($meta_array) == 0) { return false; } - - /** - * Clear all annotations belonging to a given owner_guid - * - * @param int $owner_guid The owner - */ - function clear_metadata_by_owner($owner_guid) - { - global $CONFIG; - - $owner_guid = (int)$owner_guid; - - $metas = get_data("SELECT id from {$CONFIG->dbprefix}metadata WHERE owner_guid=$owner_guid"); - $deleted = 0; - - foreach ($metas as $id) - { - if (delete_metadata($id->id)) // Is this the best way? - $deleted++; + + $where = array(); + + $mindex = 1; + $join = ""; + $metawhere = array(); + $meta_array_operator = sanitise_string($meta_array_operator); + foreach($meta_array as $meta_name => $meta_value) { + $meta_n = get_metastring_id($meta_name); + $meta_v = get_metastring_id($meta_value); + $join .= " JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid "; + /*if ($meta_name!=="") + $where[] = "m{$mindex}.name_id='$meta_n'"; + if ($meta_value!=="") + $where[] = "m{$mindex}.value_id='$meta_v'";*/ + $metawhere[] = "(m{$mindex}.name_id='$meta_n' AND m{$mindex}.value_id='$meta_v')"; + $mindex++; + } + $where[] = "(".implode($meta_array_operator, $metawhere).")"; + + $entity_type = sanitise_string($entity_type); + $entity_subtype = get_subtype_id($entity_type, $entity_subtype); + $limit = (int)$limit; + $offset = (int)$offset; + if ($order_by == "") { + $order_by = "e.time_created desc"; + } + $order_by = sanitise_string($order_by); + if ((is_array($owner_guid) && (count($owner_guid)))) { + foreach($owner_guid as $key => $guid) { + $owner_guid[$key] = (int) $guid; } - - return $deleted; + } else { + $owner_guid = (int) $owner_guid; } - - /** - * Handler called by trigger_plugin_hook on the "export" event. - */ - function export_metadata_plugin_hook($hook, $entity_type, $returnvalue, $params) - { - // Sanity check values - if ((!is_array($params)) && (!isset($params['guid']))) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:GUIDNotForExport')); - - if (!is_array($returnvalue)) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue')); - - $guid = (int)$params['guid']; - $name = $params['name']; - - $result = get_metadata_for_entity($guid); - - if ($result) - { - foreach ($result as $r) - $returnvalue[] = $r->export(); + + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + //$access = get_access_list(); + + if ($entity_type!="") { + $where[] = "e.type = '{$entity_type}'"; + } + + if ($entity_subtype) { + $where[] = "e.subtype = {$entity_subtype}"; + } + + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + if (is_array($owner_guid)) { + $where[] = "e.container_guid in (".implode(",",$owner_guid).")"; + } else if ($owner_guid > 0) { + $where[] = "e.container_guid = {$owner_guid}"; + } + + //if ($owner_guid > 0) + // $where[] = "e.container_guid = {$owner_guid}"; + + if ($count) { + $query = "SELECT count(distinct e.guid) as total "; + } else { + $query = "SELECT distinct e.* "; + } + + $query .= " from {$CONFIG->dbprefix}entities e {$join} where"; + foreach ($where as $w) { + $query .= " $w and "; + } + $query .= get_access_sql_suffix("e"); // Add access controls + + $mindex = 1; + foreach($meta_array as $meta_name => $meta_value) { + $query .= ' and ' . get_access_sql_suffix("m{$mindex}"); // Add access controls + $mindex++; + } + + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; } - - return $returnvalue; } - - /** - * Takes in a comma-separated string and returns an array of tags which have been trimmed and set to lower case - * - * @param string $string Comma-separated tag string - * @return array|false An array of strings, or false on failure - */ - function string_to_tag_array($string) { - - if (is_string($string)) { - $ar = explode(",",$string); - $ar = array_map('trim', $ar); // trim blank spaces - $ar = array_map('elgg_strtolower', $ar); // make lower case : [Marcus Povey 20090605 - Using mb wrapper function using UTF8 safe function where available] - $ar = array_filter($ar, 'is_not_null'); // Remove null values - return $ar; + return false; +} + +/** + * Returns a viewable list of entities based on the given search criteria. + * + * @see elgg_view_entity_list + * + * @param array $meta_array Array of 'name' => 'value' pairs + * @param string $entity_type The type of entity to look for, eg 'site' or 'object' + * @param string $entity_subtype The subtype of the entity. + * @param int $limit + * @param int $offset + * @param string $order_by Optional ordering. + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow users to toggle to the gallery view. Default: true + * @param true|false $pagination Display pagination? Default: true + * @return string List of ElggEntities suitable for display + */ +function list_entities_from_metadata_multi($meta_array, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) { + $offset = (int) get_input('offset'); + $limit = (int) $limit; + $count = get_entities_from_metadata_multi($meta_array, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", $site_guid, true); + $entities = get_entities_from_metadata_multi($meta_array, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", $site_guid, false); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); +} + +/** + * Clear all the metadata for a given entity, assuming you have access to that metadata. + * + * @param int $guid + */ +function clear_metadata($entity_guid) { + global $CONFIG; + + $entity_guid = (int)$entity_guid; + if ($entity = get_entity($entity_guid)) { + if ($entity->canEdit()) { + return delete_data("DELETE from {$CONFIG->dbprefix}metadata where entity_guid={$entity_guid}"); } - return false; - } - - /** - * Takes a metadata array (which has all kinds of properties) and turns it into a simple array of strings - * - * @param array $array Metadata array - * @return array Array of strings - */ - function metadata_array_to_values($array) { - - $valuearray = array(); - - if (is_array($array)) { - foreach($array as $element) { - $valuearray[] = $element->value; - } + return false; +} + +/** + * Clear all annotations belonging to a given owner_guid + * + * @param int $owner_guid The owner + */ +function clear_metadata_by_owner($owner_guid) { + global $CONFIG; + + $owner_guid = (int)$owner_guid; + + $metas = get_data("SELECT id from {$CONFIG->dbprefix}metadata WHERE owner_guid=$owner_guid"); + $deleted = 0; + + foreach ($metas as $id) { + // Is this the best way? + if (delete_metadata($id->id)) { + $deleted++; } - - return $valuearray; - } - - /** - * Get the URL for this item of metadata, by default this links to the export handler in the current view. - * - * @param int $id - */ - function get_metadata_url($id) - { - $id = (int)$id; - - if ($extender = get_metadata($id)) { - return get_extender_url($extender); - } - return false; + + return $deleted; +} + +/** + * Handler called by trigger_plugin_hook on the "export" event. + */ +function export_metadata_plugin_hook($hook, $entity_type, $returnvalue, $params) { + // Sanity check values + if ((!is_array($params)) && (!isset($params['guid']))) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:GUIDNotForExport')); } - - /** - * Mark entities with a particular type and subtype as having access permissions - * that can be changed independently from their parent entity - * - * @param string $type The type - object, user, etc - * @param string $subtype The subtype; all subtypes by default - */ - function register_metadata_as_independent($type, $subtype = '*') { - global $CONFIG; - if (!isset($CONFIG->independents)) $CONFIG->independents = array(); - $CONFIG->independents[$type][$subtype] = true; + + if (!is_array($returnvalue)) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue')); } - - /** - * Determines whether entities of a given type and subtype should not change - * their metadata in line with their parent entity - * - * @param string $type The type - object, user, etc - * @param string $subtype The entity subtype - * @return true|false - */ - function is_metadata_independent($type, $subtype) { - global $CONFIG; - if (empty($CONFIG->independents)) return false; - if (!empty($CONFIG->independents[$type][$subtype]) - || !empty($CONFIG->independents[$type]['*'])) return true; + + $guid = (int)$params['guid']; + $name = $params['name']; + + $result = get_metadata_for_entity($guid); + + if ($result) { + foreach ($result as $r) { + $returnvalue[] = $r->export(); + } + } + + return $returnvalue; +} + +/** + * Takes in a comma-separated string and returns an array of tags which have been trimmed and set to lower case + * + * @param string $string Comma-separated tag string + * @return array|false An array of strings, or false on failure + */ +function string_to_tag_array($string) { + if (is_string($string)) { + $ar = explode(",",$string); + $ar = array_map('trim', $ar); // trim blank spaces + $ar = array_map('elgg_strtolower', $ar); // make lower case : [Marcus Povey 20090605 - Using mb wrapper function using UTF8 safe function where available] + $ar = array_filter($ar, 'is_not_null'); // Remove null values + return $ar; + } + return false; + +} + +/** + * Takes a metadata array (which has all kinds of properties) and turns it into a simple array of strings + * + * @param array $array Metadata array + * @return array Array of strings + */ +function metadata_array_to_values($array) { + $valuearray = array(); + + if (is_array($array)) { + foreach($array as $element) { + $valuearray[] = $element->value; + } + } + + return $valuearray; +} + +/** + * Get the URL for this item of metadata, by default this links to the export handler in the current view. + * + * @param int $id + */ +function get_metadata_url($id) { + $id = (int)$id; + + if ($extender = get_metadata($id)) { + return get_extender_url($extender); + } + return false; +} + +/** + * Mark entities with a particular type and subtype as having access permissions + * that can be changed independently from their parent entity + * + * @param string $type The type - object, user, etc + * @param string $subtype The subtype; all subtypes by default + */ +function register_metadata_as_independent($type, $subtype = '*') { + global $CONFIG; + if (!isset($CONFIG->independents)) { + $CONFIG->independents = array(); + } + $CONFIG->independents[$type][$subtype] = true; +} + +/** + * Determines whether entities of a given type and subtype should not change + * their metadata in line with their parent entity + * + * @param string $type The type - object, user, etc + * @param string $subtype The entity subtype + * @return true|false + */ +function is_metadata_independent($type, $subtype) { + global $CONFIG; + if (empty($CONFIG->independents)) { return false; } - - /** - * When an entity is updated, resets the access ID on all of its child metadata - * - * @param string $event The name of the event - * @param string $object_type The type of object - * @param ElggEntity $object The entity itself - */ - function metadata_update($event, $object_type, $object) { - if ($object instanceof ElggEntity) { - if (!is_metadata_independent($object->getType(), $object->getSubtype())) { - global $CONFIG; - $access_id = (int) $object->access_id; - $guid = (int) $object->getGUID(); - update_data("update {$CONFIG->dbprefix}metadata set access_id = {$access_id} where entity_guid = {$guid}"); - } - } - return true; + if (!empty($CONFIG->independents[$type][$subtype]) + || !empty($CONFIG->independents[$type]['*'])) { + return true; + } + return false; +} + +/** + * When an entity is updated, resets the access ID on all of its child metadata + * + * @param string $event The name of the event + * @param string $object_type The type of object + * @param ElggEntity $object The entity itself + */ +function metadata_update($event, $object_type, $object) { + if ($object instanceof ElggEntity) { + if (!is_metadata_independent($object->getType(), $object->getSubtype())) { + global $CONFIG; + $access_id = (int) $object->access_id; + $guid = (int) $object->getGUID(); + update_data("update {$CONFIG->dbprefix}metadata set access_id = {$access_id} where entity_guid = {$guid}"); + } } - - /** - * Register a metadata url handler. - * - * @param string $function_name The function. - * @param string $extender_name The name, default 'all'. - */ - function register_metadata_url_handler($function_name, $extender_name = "all") { - return register_extender_url_handler($function_name, 'metadata', $extender_name); - } - - /** Register the hook */ - register_plugin_hook("export", "all", "export_metadata_plugin_hook", 2); - /** Call a function whenever an entity is updated **/ - register_elgg_event_handler('update','all','metadata_update'); - -?> + return true; +} + +/** + * Register a metadata url handler. + * + * @param string $function_name The function. + * @param string $extender_name The name, default 'all'. + */ +function register_metadata_url_handler($function_name, $extender_name = "all") { + return register_extender_url_handler($function_name, 'metadata', $extender_name); +} + +/** Register the hook */ +register_plugin_hook("export", "all", "export_metadata_plugin_hook", 2); +/** Call a function whenever an entity is updated **/ +register_elgg_event_handler('update','all','metadata_update'); \ No newline at end of file diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php index 31981efab..519d186e4 100644 --- a/engine/lib/metastrings.php +++ b/engine/lib/metastrings.php @@ -1,178 +1,188 @@ - * @link http://elgg.org/ - */ - - /** Cache metastrings for a page */ - $METASTRINGS_CACHE = array(); - - /** Keep a record of strings we know don't exist */ - $METASTRINGS_DEADNAME_CACHE = array(); - - /** - * Return the meta string id for a given tag, or false. - * - * @param string $string The value (whatever that is) to be stored - * @param bool $case_sensitive Do we want to make the query case sensitive? - * @return mixed Integer tag or false. - */ - function get_metastring_id($string, $case_sensitive = true) - { - global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE; - - $string = sanitise_string($string); - $result = array_search($string, $METASTRINGS_CACHE); - if ($result!==false) { - - if (isset($CONFIG->debug) && $CONFIG->debug) - error_log("** Returning id for string:$string from cache."); - - return $result; - } - - // See if we have previously looked for this and found nothing - if (in_array($string, $METASTRINGS_DEADNAME_CACHE)) - return false; - - // Experimental memcache - $msfc = null; - static $metastrings_memcache; - if ((!$metastrings_memcache) && (is_memcache_available())) - $metastrings_memcache = new ElggMemcache('metastrings_memcache'); - if ($metastrings_memcache) $msfc = $metastrings_memcache->load($string); - if ($msfc) return $msfc; - - // Case sensitive - $cs = ""; - if ($case_sensitive) $cs = " BINARY "; - - $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where string=$cs'$string' limit 1"); - if ($row) { - $METASTRINGS_CACHE[$row->id] = $row->string; // Cache it - - // Attempt to memcache it if memcache is available - if ($metastrings_memcache) $metastrings_memcache->save($row->string, $row->id); - - if (isset($CONFIG->debug) && $CONFIG->debug) - error_log("** Cacheing string '{$row->string}'"); - - return $row->id; +/** + * Elgg metastrngs + * Functions to manage object metastrings. + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + */ + +/** Cache metastrings for a page */ +$METASTRINGS_CACHE = array(); + +/** Keep a record of strings we know don't exist */ +$METASTRINGS_DEADNAME_CACHE = array(); + +/** + * Return the meta string id for a given tag, or false. + * + * @param string $string The value (whatever that is) to be stored + * @param bool $case_sensitive Do we want to make the query case sensitive? + * @return mixed Integer tag or false. + */ +function get_metastring_id($string, $case_sensitive = true) { + global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE; + + $string = sanitise_string($string); + $result = array_search($string, $METASTRINGS_CACHE); + if ($result!==false) { + if (isset($CONFIG->debug) && $CONFIG->debug) { + error_log("** Returning id for string:$string from cache."); } - else - $METASTRINGS_DEADNAME_CACHE[$string] = $string; - + + return $result; + } + + // See if we have previously looked for this and found nothing + if (in_array($string, $METASTRINGS_DEADNAME_CACHE)) { return false; } - - /** - * When given an ID, returns the corresponding metastring - * - * @param int $id Metastring ID - * @return string Metastring - */ - function get_metastring($id) { - - global $CONFIG, $METASTRINGS_CACHE; - - $id = (int) $id; - - if (isset($METASTRINGS_CACHE[$id])) { - - if ($CONFIG->debug) - error_log("** Returning string for id:$id from cache."); - - return $METASTRINGS_CACHE[$id]; + + // Experimental memcache + $msfc = null; + static $metastrings_memcache; + if ((!$metastrings_memcache) && (is_memcache_available())) { + $metastrings_memcache = new ElggMemcache('metastrings_memcache'); + } + if ($metastrings_memcache) { + $msfc = $metastrings_memcache->load($string); + } + if ($msfc) { + return $msfc; + } + + // Case sensitive + $cs = ""; + if ($case_sensitive) { + $cs = " BINARY "; + } + + $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where string=$cs'$string' limit 1"); + if ($row) { + $METASTRINGS_CACHE[$row->id] = $row->string; // Cache it + + // Attempt to memcache it if memcache is available + if ($metastrings_memcache) { + $metastrings_memcache->save($row->string, $row->id); } - - $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where id='$id' limit 1"); - if ($row) { - $METASTRINGS_CACHE[$id] = $row->string; // Cache it - - if ($CONFIG->debug) - error_log("** Cacheing string '{$row->string}'"); - - return $row->string; + + if (isset($CONFIG->debug) && $CONFIG->debug) { + error_log("** Cacheing string '{$row->string}'"); } - - return false; - + + return $row->id; + } else { + $METASTRINGS_DEADNAME_CACHE[$string] = $string; + } + + return false; +} + +/** + * When given an ID, returns the corresponding metastring + * + * @param int $id Metastring ID + * @return string Metastring + */ +function get_metastring($id) { + global $CONFIG, $METASTRINGS_CACHE; + + $id = (int) $id; + + if (isset($METASTRINGS_CACHE[$id])) { + if ($CONFIG->debug) { + error_log("** Returning string for id:$id from cache."); + } + + return $METASTRINGS_CACHE[$id]; } - /** - * Add a metastring. - * It returns the id of the tag, whether by creating it or updating it. - * - * @param string $string The value (whatever that is) to be stored - * @param bool $case_sensitive Do we want to make the query case sensitive? - * @return mixed Integer tag or false. - */ - function add_metastring($string, $case_sensitive = true) - { - global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE; - - $sanstring = sanitise_string($string); - - $id = get_metastring_id($string, $case_sensitive); - if ($id) return $id; - - $result = insert_data("INSERT into {$CONFIG->dbprefix}metastrings (string) values ('$sanstring')"); - if ($result) { - $METASTRINGS_CACHE[$result] = $string; - if (isset($METASTRINGS_DEADNAME_CACHE[$string])) unset($METASTRINGS_DEADNAME_CACHE[$string]); + $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where id='$id' limit 1"); + if ($row) { + $METASTRINGS_CACHE[$id] = $row->string; // Cache it + + if ($CONFIG->debug) { + error_log("** Cacheing string '{$row->string}'"); } - - return $result; + + return $row->string; + } + + return false; +} + +/** + * Add a metastring. + * It returns the id of the tag, whether by creating it or updating it. + * + * @param string $string The value (whatever that is) to be stored + * @param bool $case_sensitive Do we want to make the query case sensitive? + * @return mixed Integer tag or false. + */ +function add_metastring($string, $case_sensitive = true) { + global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE; + + $sanstring = sanitise_string($string); + + $id = get_metastring_id($string, $case_sensitive); + if ($id) { + return $id; } - - /** - * Delete any orphaned entries in metastrings. This is run by the garbage collector. - * - */ - function delete_orphaned_metastrings() - { - global $CONFIG; - - // If memcache is enabled then we need to flush it of deleted values - if (is_memcache_available()) - { - $select_query = " - SELECT * - from {$CONFIG->dbprefix}metastrings where - ( - (id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND - (id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND - (id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND - (id not in (select value_id from {$CONFIG->dbprefix}annotations)) - )"; - - $dead = get_data($select_query); - if ($dead) - { - static $metastrings_memcache; - if (!$metastrings_memcache) - $metastrings_memcache = new ElggMemcache('metastrings_memcache'); - foreach ($dead as $d) - $metastrings_memcache->delete($d->string); + + $result = insert_data("INSERT into {$CONFIG->dbprefix}metastrings (string) values ('$sanstring')"); + if ($result) { + $METASTRINGS_CACHE[$result] = $string; + if (isset($METASTRINGS_DEADNAME_CACHE[$string])) { + unset($METASTRINGS_DEADNAME_CACHE[$string]); + } + } + + return $result; +} + +/** + * Delete any orphaned entries in metastrings. This is run by the garbage collector. + * + */ +function delete_orphaned_metastrings() { + global $CONFIG; + + // If memcache is enabled then we need to flush it of deleted values + if (is_memcache_available()) { + $select_query = " + SELECT * + from {$CONFIG->dbprefix}metastrings where + ( + (id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND + (id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND + (id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND + (id not in (select value_id from {$CONFIG->dbprefix}annotations)) + )"; + + $dead = get_data($select_query); + if ($dead) { + static $metastrings_memcache; + if (!$metastrings_memcache) { + $metastrings_memcache = new ElggMemcache('metastrings_memcache'); + } + + foreach ($dead as $d) { + $metastrings_memcache->delete($d->string); } } - - $query = " - DELETE - from {$CONFIG->dbprefix}metastrings where - ( - (id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND - (id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND - (id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND - (id not in (select value_id from {$CONFIG->dbprefix}annotations)) - )"; - - return delete_data($query); } - -?> \ No newline at end of file + + $query = " + DELETE + from {$CONFIG->dbprefix}metastrings where + ( + (id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND + (id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND + (id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND + (id not in (select value_id from {$CONFIG->dbprefix}annotations)) + )"; + + return delete_data($query); +} \ No newline at end of file diff --git a/engine/lib/notification.php b/engine/lib/notification.php index d80c17ca0..6284e874d 100644 --- a/engine/lib/notification.php +++ b/engine/lib/notification.php @@ -1,430 +1,446 @@ handler = $handler; - if ($params) - { - foreach ($params as $k => $v) - $NOTIFICATION_HANDLERS[$method]->$k = $v; +/** + * Notifications + * This file contains classes and functions which allow plugins to register and send notifications. + * + * There are notification methods which are provided out of the box (see notification_init() ). Each method + * is identified by a string, e.g. "email". + * + * To register an event use register_notification_handler() and pass the method name and a handler function. + * + * To send a notification call notify() passing it the method you wish to use combined with a number of method + * specific addressing parameters. + * + * Catch NotificationException to trap errors. + * + * @package Elgg + * @subpackage API + + * @author Curverider Ltd + + * @link http://elgg.org/ + */ + +/** Notification handlers */ +$NOTIFICATION_HANDLERS = array(); + +/** + * This function registers a handler for a given notification type (eg "email") + * + * @param string $method The method + * @param string $handler The handler function, in the format "handler(ElggEntity $from, ElggUser $to, $subject, $message, array $params = NULL)". This function should return false on failure, and true/a tracking message ID on success. + * @param array $params A associated array of other parameters for this handler defining some properties eg. supported message length or rich text support. + */ +function register_notification_handler($method, $handler, $params = NULL) { + global $NOTIFICATION_HANDLERS; + + if (is_callable($handler)) { + $NOTIFICATION_HANDLERS[$method] = new stdClass; + + $NOTIFICATION_HANDLERS[$method]->handler = $handler; + if ($params) { + foreach ($params as $k => $v) { + $NOTIFICATION_HANDLERS[$method]->$k = $v; } - - return true; } - - return false; + + return true; + } + + return false; +} + +/** + * Notify a user via their preferences. + * + * @param mixed $to Either a guid or an array of guid's to notify. + * @param int $from GUID of the sender, which may be a user, site or object. + * @param string $subject Message subject. + * @param string $message Message body. + * @param array $params Misc additional parameters specific to various methods. + * @param mixed $methods_override A string, or an array of strings specifying the delivery methods to use - or leave blank + * for delivery using the user's chosen delivery methods. + * @return array Compound array of each delivery user/delivery method's success or failure. + * @throws NotificationException + */ +function notify_user($to, $from, $subject, $message, array $params = NULL, $methods_override = "") { + global $NOTIFICATION_HANDLERS, $CONFIG; + + // Sanitise + if (!is_array($to)) { + $to = array((int)$to); + } + $from = (int)$from; + //$subject = sanitise_string($subject); + + // Get notification methods + if (($methods_override) && (!is_array($methods_override))) { + $methods_override = array($methods_override); } - - /** - * Notify a user via their preferences. - * - * @param mixed $to Either a guid or an array of guid's to notify. - * @param int $from GUID of the sender, which may be a user, site or object. - * @param string $subject Message subject. - * @param string $message Message body. - * @param array $params Misc additional parameters specific to various methods. - * @param mixed $methods_override A string, or an array of strings specifying the delivery methods to use - or leave blank - * for delivery using the user's chosen delivery methods. - * @return array Compound array of each delivery user/delivery method's success or failure. - * @throws NotificationException - */ - function notify_user($to, $from, $subject, $message, array $params = NULL, $methods_override = "") - { - global $NOTIFICATION_HANDLERS, $CONFIG; - - // Sanitise - if (!is_array($to)) - $to = array((int)$to); - $from = (int)$from; - //$subject = sanitise_string($subject); - - // Get notification methods - if (($methods_override) && (!is_array($methods_override))) - $methods_override = array($methods_override); - - $result = array(); - - foreach ($to as $guid) - { - // Results for a user are... - $result[$guid] = array(); - - if ($guid) { // Is the guid > 0? - // Are we overriding delivery? - $methods = $methods_override; - if (!$methods) - { - $tmp = (array)get_user_notification_settings($guid); - $methods = array(); - foreach($tmp as $k => $v) - if ($v) $methods[] = $k; // Add method if method is turned on for user! + + $result = array(); + + foreach ($to as $guid) { + // Results for a user are... + $result[$guid] = array(); + + if ($guid) { // Is the guid > 0? + // Are we overriding delivery? + $methods = $methods_override; + if (!$methods) { + $tmp = (array)get_user_notification_settings($guid); + $methods = array(); + foreach($tmp as $k => $v) { + // Add method if method is turned on for user! + if ($v) { + $methods[] = $k; + } } - - if ($methods) - { - // Deliver - foreach ($methods as $method) - { - // Extract method details from list - $details = $NOTIFICATION_HANDLERS[$method]; - $handler = $details->handler; - - if ((!$NOTIFICATION_HANDLERS[$method]) || (!$handler)) - error_log(sprintf(elgg_echo('NotificationException:NoHandlerFound'), $method)); - - if ($CONFIG->debug) - error_log("Sending message to $guid using $method"); - - // Trigger handler and retrieve result. - try { - $result[$guid][$method] = $handler( - $from ? get_entity($from) : NULL, // From entity - get_entity($guid), // To entity - $subject, // The subject - $message, // Message - $params // Params - ); - } catch (Exception $e) { - error_log($e->getMessage()); - } - + } + + if ($methods) { + // Deliver + foreach ($methods as $method) { + // Extract method details from list + $details = $NOTIFICATION_HANDLERS[$method]; + $handler = $details->handler; + + if ((!$NOTIFICATION_HANDLERS[$method]) || (!$handler)) { + error_log(sprintf(elgg_echo('NotificationException:NoHandlerFound'), $method)); + } + + if ($CONFIG->debug) { + error_log("Sending message to $guid using $method"); + } + + // Trigger handler and retrieve result. + try { + $result[$guid][$method] = $handler( + $from ? get_entity($from) : NULL, // From entity + get_entity($guid), // To entity + $subject, // The subject + $message, // Message + $params // Params + ); + } catch (Exception $e) { + error_log($e->getMessage()); } + } - } + } } - - return $result; } - - /** - * Get the notification settings for a given user. - * - * @param int $user_guid The user id - * @return stdClass - */ - function get_user_notification_settings($user_guid = 0) - { - $user_guid = (int)$user_guid; - - if ($user_guid == 0) $user_guid = get_loggedin_userid(); - - $all_metadata = get_metadata_for_entity($user_guid); - if ($all_metadata) - { - $prefix = "notification:method:"; - $return = new stdClass; - - foreach ($all_metadata as $meta) - { - $name = substr($meta->name, strlen($prefix)); - $value = $meta->value; - - if (strpos($meta->name, $prefix) === 0) - $return->$name = $value; - } - return $return; - } - - return false; + return $result; +} + +/** + * Get the notification settings for a given user. + * + * @param int $user_guid The user id + * @return stdClass + */ +function get_user_notification_settings($user_guid = 0) { + $user_guid = (int)$user_guid; + + if ($user_guid == 0) { + $user_guid = get_loggedin_userid(); } - - /** - * Set a user notification pref. - * - * @param int $user_guid The user id. - * @param string $method The delivery method (eg. email) - * @param bool $value On(true) or off(false). - * @return bool - */ - function set_user_notification_setting($user_guid, $method, $value) - { - $user_guid = (int)$user_guid; - $method = sanitise_string($method); - - $user = get_entity($user_guid); - if (!$user) $user = get_loggedin_user(); - - if (($user) && ($user instanceof ElggUser)) - { - $prefix = "notification:method:$method"; - $user->$prefix = $value; - $user->save(); - - return true; + + $all_metadata = get_metadata_for_entity($user_guid); + if ($all_metadata) { + $prefix = "notification:method:"; + $return = new stdClass; + + foreach ($all_metadata as $meta) { + $name = substr($meta->name, strlen($prefix)); + $value = $meta->value; + + if (strpos($meta->name, $prefix) === 0) { + $return->$name = $value; + } } - - return false; + + return $return; } - - /** - * Notification exception. - * @author Curverider Ltd - */ - class NotificationException extends Exception {} - - - /** - * Send a notification via email. - * - * @param ElggEntity $from The from user/site/object - * @param ElggUser $to To which user? - * @param string $subject The subject of the message. - * @param string $message The message body - * @param array $params Optional parameters (none taken in this instance) - * @return bool - */ - function email_notify_handler(ElggEntity $from, ElggUser $to, $subject, $message, array $params = NULL) - { - global $CONFIG; - - if (!$from) - throw new NotificationException(sprintf(elgg_echo('NotificationException:MissingParameter'), 'from')); - - if (!$to) - throw new NotificationException(sprintf(elgg_echo('NotificationException:MissingParameter'), 'to')); - - if ($to->email=="") - throw new NotificationException(sprintf(elgg_echo('NotificationException:NoEmailAddress'), $to->guid)); - - // Sanitise subject - $subject = preg_replace("/(\r\n|\r|\n)/", " ", $subject); // Strip line endings - - // To - $to = $to->email; - - // From - $site = get_entity($CONFIG->site_guid); - if ((isset($from->email)) && (!($from instanceof ElggUser))) // If there's an email address, use it - but only if its not from a user. - $from = $from->email; - else if (($site) && (isset($site->email))) // Has the current site got a from email address? - $from = $site->email; - else if (isset($from->url)) // If we have a url then try and use that. - { - $breakdown = parse_url($from->url); - $from = 'noreply@' . $breakdown['host']; // Handle anything with a url - } - else // If all else fails, use the domain of the site. - $from = 'noreply@' . get_site_domain($CONFIG->site_guid); - - if (is_callable('mb_internal_encoding')) { - mb_internal_encoding('UTF-8'); - } - $site = get_entity($CONFIG->site_guid); - $sitename = $site->name; - if (is_callable('mb_encode_mimeheader')) { - $sitename = mb_encode_mimeheader($site->name,"UTF-8", "B"); - } - - $header_eol = "\r\n"; - if ( - (isset($CONFIG->broken_mta)) && - ($CONFIG->broken_mta) - ) - $header_eol = "\n"; // Allow non-RFC 2822 mail headers to support some broken MTAs - - $from_email = "\"$sitename\" <$from>"; - if (strtolower(substr(PHP_OS, 0 , 3)) == 'win') - $from_email = "$from"; // Windows is somewhat broken, so we use a different format from header - - $headers = "From: $from_email{$header_eol}" - . "Content-Type: text/plain; charset=UTF-8; format=flowed{$header_eol}" - . "MIME-Version: 1.0{$header_eol}" - . "Content-Transfer-Encoding: 8bit{$header_eol}"; - - if (is_callable('mb_encode_mimeheader')) { - $subject = mb_encode_mimeheader($subject,"UTF-8", "B"); - } - - // Format message - $message = html_entity_decode($message, ENT_COMPAT, 'UTF-8'); // Decode any html entities - $message = strip_tags($message); // Strip tags from message - $message = preg_replace("/(\r\n|\r)/", "\n", $message); // Convert to unix line endings in body - $message = preg_replace("/^From/", ">From", $message); // Change lines starting with From to >From - - return mail($to, $subject, wordwrap($message), $headers); + + return false; +} + +/** + * Set a user notification pref. + * + * @param int $user_guid The user id. + * @param string $method The delivery method (eg. email) + * @param bool $value On(true) or off(false). + * @return bool + */ +function set_user_notification_setting($user_guid, $method, $value) { + $user_guid = (int)$user_guid; + $method = sanitise_string($method); + + $user = get_entity($user_guid); + if (!$user) { + $user = get_loggedin_user(); } - /** - * Correctly initialise notifications and register the email handler. - * - */ - function notification_init() - { - // Register a notification handler for the default email method - register_notification_handler("email", "email_notify_handler"); - - // Add settings view to user settings & register action - extend_elgg_settings_page('notifications/settings/usersettings', 'usersettings/user'); - - register_plugin_hook('usersettings:save','user','notification_user_settings_save'); - - //register_action("notifications/settings/usersettings/save"); - - - // Register some APIs - expose_function('user.notification.get', 'get_user_notification_settings', array( - 'user_guid' => array ('type' => 'int') - ), elgg_echo('user.notification.get')); - - expose_function('user.notification.set', 'set_user_notification_settings', array( - 'user_guid' => array ('type' => 'int'), - 'method' => array ('type' => 'string'), - 'value' => array ('type' => 'bool') - ), elgg_echo('user.notification.set')); - + if (($user) && ($user instanceof ElggUser)) { + $prefix = "notification:method:$method"; + $user->$prefix = $value; + $user->save(); + + return true; } - - function notification_user_settings_save() { - - global $CONFIG; - include($CONFIG->path . "actions/notifications/settings/usersettings/save.php"); - + + return false; +} + +/** + * Notification exception. + * @author Curverider Ltd + */ +class NotificationException extends Exception {} + + +/** + * Send a notification via email. + * + * @param ElggEntity $from The from user/site/object + * @param ElggUser $to To which user? + * @param string $subject The subject of the message. + * @param string $message The message body + * @param array $params Optional parameters (none taken in this instance) + * @return bool + */ +function email_notify_handler(ElggEntity $from, ElggUser $to, $subject, $message, array $params = NULL) { + global $CONFIG; + + if (!$from) { + throw new NotificationException(sprintf(elgg_echo('NotificationException:MissingParameter'), 'from')); } - - /** - * Register an entity type and subtype to be eligible for notifications - * - * @param string $entity_type The type of entity - * @param string $object_subtype Its subtype - * @param string $english_name It's English notification string (eg "New blog post") - */ - function register_notification_object($entity_type, $object_subtype, $english_name) { - global $CONFIG; - - if ($entity_type == '') $entity_type = '__BLANK__'; - if ($object_subtype == '') $object_subtype = '__BLANK__'; - - if (!isset($CONFIG->register_objects)) { - $CONFIG->register_objects = array(); - } - if (!isset($CONFIG->register_objects[$entity_type])) { - $CONFIG->register_objects[$entity_type] = array(); - } - $CONFIG->register_objects[$entity_type][$object_subtype] = $english_name; + + if (!$to) { + throw new NotificationException(sprintf(elgg_echo('NotificationException:MissingParameter'), 'to')); + } + + if ($to->email=="") { + throw new NotificationException(sprintf(elgg_echo('NotificationException:NoEmailAddress'), $to->guid)); + } + + // Sanitise subject + $subject = preg_replace("/(\r\n|\r|\n)/", " ", $subject); // Strip line endings + + // To + $to = $to->email; + + // From + $site = get_entity($CONFIG->site_guid); + // If there's an email address, use it - but only if its not from a user. + if ((isset($from->email)) && (!($from instanceof ElggUser))) { + $from = $from->email; + } else if (($site) && (isset($site->email))) { + // Has the current site got a from email address? + $from = $site->email; + } else if (isset($from->url)) { + // If we have a url then try and use that. + $breakdown = parse_url($from->url); + $from = 'noreply@' . $breakdown['host']; // Handle anything with a url + } else { + // If all else fails, use the domain of the site. + $from = 'noreply@' . get_site_domain($CONFIG->site_guid); + } + + if (is_callable('mb_internal_encoding')) { + mb_internal_encoding('UTF-8'); + } + $site = get_entity($CONFIG->site_guid); + $sitename = $site->name; + if (is_callable('mb_encode_mimeheader')) { + $sitename = mb_encode_mimeheader($site->name,"UTF-8", "B"); + } + + $header_eol = "\r\n"; + if ( + (isset($CONFIG->broken_mta)) && + ($CONFIG->broken_mta) + ) { + // Allow non-RFC 2822 mail headers to support some broken MTAs + $header_eol = "\n"; } - - /** - * Establish a 'notify' relationship between the user and a content author - * - * @param int $user_guid The GUID of the user who wants to follow a user's content - * @param int $author_guid The GUID of the user whose content the user wants to follow - * @return true|false Depending on success - */ - function register_notification_interest($user_guid, $author_guid) { - return add_entity_relationship($user_guid, 'notify', $author_guid); + + $from_email = "\"$sitename\" <$from>"; + if (strtolower(substr(PHP_OS, 0 , 3)) == 'win') { + // Windows is somewhat broken, so we use a different format from header + $from_email = "$from"; } - - /** - * Remove a 'notify' relationship between the user and a content author - * - * @param int $user_guid The GUID of the user who is following a user's content - * @param int $author_guid The GUID of the user whose content the user wants to unfollow - * @return true|false Depending on success - */ - function remove_notification_interest($user_guid, $author_guid) { - return remove_entity_relationship($user_guid, 'notify', $author_guid); + + $headers = "From: $from_email{$header_eol}" + . "Content-Type: text/plain; charset=UTF-8; format=flowed{$header_eol}" + . "MIME-Version: 1.0{$header_eol}" + . "Content-Transfer-Encoding: 8bit{$header_eol}"; + + if (is_callable('mb_encode_mimeheader')) { + $subject = mb_encode_mimeheader($subject,"UTF-8", "B"); } - - /** - * Automatically triggered notification on 'create' events that looks at registered - * objects and attempts to send notifications to anybody who's interested - * - * @see register_notification_object - */ - function object_notifications($event, $object_type, $object) { - - // We only want to trigger notification events for ElggEntities - if ($object instanceof ElggEntity) { - - // Get config data - global $CONFIG, $SESSION, $NOTIFICATION_HANDLERS; - - $hookresult = trigger_plugin_hook('object:notifications',$object_type,array( - 'event' => $event, - 'object_type' => $object_type, - 'object' => $object, - ),false); - if ($hookresult === true) return true; - - // Have we registered notifications for this type of entity? - $object_type = $object->getType(); if (empty($object_type)) $object_type = '__BLANK__'; - $object_subtype = $object->getSubtype(); if (empty($object_subtype)) $object_subtype = '__BLANK__'; - if (isset($CONFIG->register_objects[$object_type][$object_subtype])) { - - $descr = $CONFIG->register_objects[$object_type][$object_subtype]; - $string = $descr . ": " . $object->getURL(); - - // Get users interested in content from this person and notify them - // (Person defined by container_guid so we can also subscribe to groups if we want) - foreach($NOTIFICATION_HANDLERS as $method => $foo) - if ($interested_users = get_entities_from_relationship('notify' . $method,$object->container_guid,true,'user','',0,'',99999)) { - - if (is_array($interested_users)) - foreach($interested_users as $user) { - if ($user instanceof ElggUser) { - - if (!$user->isBanned()) - if (($user->guid != $SESSION['user']->guid) && has_access_to_entity($object,$user) - && $object->access_id != ACCESS_PRIVATE) { - - $methodstring = trigger_plugin_hook('notify:entity:message',$object->getType(),array( - 'entity' => $object, - 'to_entity' => $user, - 'method' => $method),$string); - if (empty($methodstring) && $methodstring !== false) $methodstring = $string; - if ($methodstring !== false) - notify_user($user->guid,$object->container_guid,$descr,$methodstring,NULL,array($method)); + + // Format message + $message = html_entity_decode($message, ENT_COMPAT, 'UTF-8'); // Decode any html entities + $message = strip_tags($message); // Strip tags from message + $message = preg_replace("/(\r\n|\r)/", "\n", $message); // Convert to unix line endings in body + $message = preg_replace("/^From/", ">From", $message); // Change lines starting with From to >From + + return mail($to, $subject, wordwrap($message), $headers); +} + +/** + * Correctly initialise notifications and register the email handler. + * + */ +function notification_init() { + // Register a notification handler for the default email method + register_notification_handler("email", "email_notify_handler"); + + // Add settings view to user settings & register action + extend_elgg_settings_page('notifications/settings/usersettings', 'usersettings/user'); + + register_plugin_hook('usersettings:save','user','notification_user_settings_save'); + + //register_action("notifications/settings/usersettings/save"); + + // Register some APIs + expose_function('user.notification.get', 'get_user_notification_settings', array( + 'user_guid' => array ('type' => 'int') + ), elgg_echo('user.notification.get')); + + expose_function('user.notification.set', 'set_user_notification_settings', array( + 'user_guid' => array ('type' => 'int'), + 'method' => array ('type' => 'string'), + 'value' => array ('type' => 'bool') + ), elgg_echo('user.notification.set')); +} + +function notification_user_settings_save() { + global $CONFIG; + include($CONFIG->path . "actions/notifications/settings/usersettings/save.php"); +} + +/** + * Register an entity type and subtype to be eligible for notifications + * + * @param string $entity_type The type of entity + * @param string $object_subtype Its subtype + * @param string $english_name It's English notification string (eg "New blog post") + */ +function register_notification_object($entity_type, $object_subtype, $english_name) { + global $CONFIG; + + if ($entity_type == '') { + $entity_type = '__BLANK__'; + } + if ($object_subtype == '') { + $object_subtype = '__BLANK__'; + } + + if (!isset($CONFIG->register_objects)) { + $CONFIG->register_objects = array(); + } + + if (!isset($CONFIG->register_objects[$entity_type])) { + $CONFIG->register_objects[$entity_type] = array(); + } + + $CONFIG->register_objects[$entity_type][$object_subtype] = $english_name; +} + +/** + * Establish a 'notify' relationship between the user and a content author + * + * @param int $user_guid The GUID of the user who wants to follow a user's content + * @param int $author_guid The GUID of the user whose content the user wants to follow + * @return true|false Depending on success + */ +function register_notification_interest($user_guid, $author_guid) { + return add_entity_relationship($user_guid, 'notify', $author_guid); +} + +/** + * Remove a 'notify' relationship between the user and a content author + * + * @param int $user_guid The GUID of the user who is following a user's content + * @param int $author_guid The GUID of the user whose content the user wants to unfollow + * @return true|false Depending on success + */ +function remove_notification_interest($user_guid, $author_guid) { + return remove_entity_relationship($user_guid, 'notify', $author_guid); +} + +/** + * Automatically triggered notification on 'create' events that looks at registered + * objects and attempts to send notifications to anybody who's interested + * + * @see register_notification_object + */ +function object_notifications($event, $object_type, $object) { + // We only want to trigger notification events for ElggEntities + if ($object instanceof ElggEntity) { + + // Get config data + global $CONFIG, $SESSION, $NOTIFICATION_HANDLERS; + + $hookresult = trigger_plugin_hook('object:notifications',$object_type,array( + 'event' => $event, + 'object_type' => $object_type, + 'object' => $object, + ), false); + if ($hookresult === true) { + return true; + } + + // Have we registered notifications for this type of entity? + $object_type = $object->getType(); + if (empty($object_type)) { + $object_type = '__BLANK__'; + } + + $object_subtype = $object->getSubtype(); + if (empty($object_subtype)) { + $object_subtype = '__BLANK__'; + } + + if (isset($CONFIG->register_objects[$object_type][$object_subtype])) { + $descr = $CONFIG->register_objects[$object_type][$object_subtype]; + $string = $descr . ": " . $object->getURL(); + + // Get users interested in content from this person and notify them + // (Person defined by container_guid so we can also subscribe to groups if we want) + foreach($NOTIFICATION_HANDLERS as $method => $foo) { + $interested_users = get_entities_from_relationship('notify' . $method, + $object->container_guid, true, 'user', '', 0, '', 99999); + + if ($interested_users && is_array($interested_users)) { + foreach($interested_users as $user) { + if ($user instanceof ElggUser && !$user->isBanned()) { + if (($user->guid != $SESSION['user']->guid) && has_access_to_entity($object,$user) + && $object->access_id != ACCESS_PRIVATE) { + $methodstring = trigger_plugin_hook('notify:entity:message',$object->getType(),array( + 'entity' => $object, + 'to_entity' => $user, + 'method' => $method),$string); + if (empty($methodstring) && $methodstring !== false) { + $methodstring = $string; } - } + if ($methodstring !== false) { + notify_user($user->guid,$object->container_guid,$descr,$methodstring,NULL,array($method)); + } + } } + } } - } - } - } +} - // Register a startup event - register_elgg_event_handler('init','system','notification_init',0); - register_elgg_event_handler('create','object','object_notifications'); - -?> +// Register a startup event +register_elgg_event_handler('init','system','notification_init',0); +register_elgg_event_handler('create','object','object_notifications'); \ No newline at end of file diff --git a/engine/lib/objects.php b/engine/lib/objects.php index 8d09b178b..a81925ce1 100644 --- a/engine/lib/objects.php +++ b/engine/lib/objects.php @@ -1,376 +1,371 @@ attributes['type'] = "object"; + $this->attributes['title'] = ""; + $this->attributes['description'] = ""; + $this->attributes['tables_split'] = 2; + } /** - * ElggObject - * Representation of an "object" in the system. - * - * @package Elgg - * @subpackage Core + * Construct a new object entity, optionally from a given id value. + * + * @param mixed $guid If an int, load that GUID. + * If a db row then will attempt to load the rest of the data. + * @throws Exception if there was a problem creating the object. */ - class ElggObject extends ElggEntity - { - /** - * Initialise the attributes array. - * This is vital to distinguish between metadata and base parameters. - * - * Place your base parameters here. - */ - protected function initialise_attributes() - { - parent::initialise_attributes(); - - $this->attributes['type'] = "object"; - $this->attributes['title'] = ""; - $this->attributes['description'] = ""; - $this->attributes['tables_split'] = 2; - } - - /** - * Construct a new object entity, optionally from a given id value. - * - * @param mixed $guid If an int, load that GUID. - * If a db row then will attempt to load the rest of the data. - * @throws Exception if there was a problem creating the object. - */ - function __construct($guid = null) - { - $this->initialise_attributes(); - - if (!empty($guid)) - { - // Is $guid is a DB row - either a entity row, or a object table row. - if ($guid instanceof stdClass) { - // Load the rest - if (!$this->load($guid->guid)) - throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid)); + function __construct($guid = null) { + $this->initialise_attributes(); + + if (!empty($guid)) { + // Is $guid is a DB row - either a entity row, or a object table row. + if ($guid instanceof stdClass) { + // Load the rest + if (!$this->load($guid->guid)) { + throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid)); } - - // Is $guid is an ElggObject? Use a copy constructor - else if ($guid instanceof ElggObject) - { - foreach ($guid->attributes as $key => $value) - $this->attributes[$key] = $value; + } + + // Is $guid is an ElggObject? Use a copy constructor + else if ($guid instanceof ElggObject) { + foreach ($guid->attributes as $key => $value) { + $this->attributes[$key] = $value; } - - // Is this is an ElggEntity but not an ElggObject = ERROR! - else if ($guid instanceof ElggEntity) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggObject')); - - // We assume if we have got this far, $guid is an int - else if (is_numeric($guid)) { - if (!$this->load($guid)) IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid)); + } + + // Is this is an ElggEntity but not an ElggObject = ERROR! + else if ($guid instanceof ElggEntity) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggObject')); + } + + // We assume if we have got this far, $guid is an int + else if (is_numeric($guid)) { + if (!$this->load($guid)) { + IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid)); } - - else - throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue')); + } + + else { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue')); } } - - /** - * Override the load function. - * This function will ensure that all data is loaded (were possible), so - * if only part of the ElggObject is loaded, it'll load the rest. - * - * @param int $guid - * @return true|false - */ - protected function load($guid) - { - // Test to see if we have the generic stuff - if (!parent::load($guid)) - return false; - - // Check the type - if ($this->attributes['type']!='object') - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class())); - - // Load missing data - $row = get_object_entity_as_row($guid); - if (($row) && (!$this->isFullyLoaded())) $this->attributes['tables_loaded'] ++; // If $row isn't a cached copy then increment the counter - - // Now put these into the attributes array as core values - $objarray = (array) $row; - foreach($objarray as $key => $value) - $this->attributes[$key] = $value; - - return true; - } - - /** - * Override the save function. - * @return true|false - */ - public function save() - { - // Save generic stuff - if (!parent::save()) - return false; - - // Now save specific stuff - return create_object_entity($this->get('guid'), $this->get('title'), $this->get('description'), $this->get('container_guid')); - } - - /** - * Get sites that this object is a member of - * - * @param string $subtype Optionally, the subtype of result we want to limit to - * @param int $limit The number of results to return - * @param int $offset Any indexing offset - */ - function getSites($subtype="", $limit = 10, $offset = 0) { - return get_site_objects($this->getGUID(), $subtype, $limit, $offset); - } - - /** - * Add this object to a particular site - * - * @param int $site_guid The guid of the site to add it to - * @return true|false - */ - function addToSite($site_guid) { - return add_site_object($this->getGUID(), $site_guid); - } + } - /** - * Set the container for this object. - * - * @param int $container_guid The ID of the container. - * @return bool - */ - function setContainer($container_guid) - { - $container_guid = (int)$container_guid; - - return $this->set('container_guid', $container_guid); + /** + * Override the load function. + * This function will ensure that all data is loaded (were possible), so + * if only part of the ElggObject is loaded, it'll load the rest. + * + * @param int $guid + * @return true|false + */ + protected function load($guid) { + // Test to see if we have the generic stuff + if (!parent::load($guid)) { + return false; } - - /** - * Return the container GUID of this object. - * - * @return int - */ - function getContainer() - { - return $this->get('container_guid'); + + // Check the type + if ($this->attributes['type']!='object') { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class())); } - - /** - * As getContainer(), but returns the whole entity. - * - * @return mixed ElggGroup object or false. - */ - function getContainerEntity() - { - $result = get_entity($this->getContainer()); - - if (($result) && ($result instanceof ElggGroup)) - return $result; - - return false; + + // Load missing data + $row = get_object_entity_as_row($guid); + if (($row) && (!$this->isFullyLoaded())) { + // If $row isn't a cached copy then increment the counter + $this->attributes['tables_loaded'] ++; } - - /** - * Get the collections associated with a object. - * - * @param string $subtype Optionally, the subtype of result we want to limit to - * @param int $limit The number of results to return - * @param int $offset Any indexing offset - * @return unknown - */ - //public function getCollections($subtype="", $limit = 10, $offset = 0) { get_object_collections($this->getGUID(), $subtype, $limit, $offset); } - - // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// - - /** - * Return an array of fields which can be exported. - */ - public function getExportableValues() - { - return array_merge(parent::getExportableValues(), array( - 'title', - 'description', - )); + + // Now put these into the attributes array as core values + $objarray = (array) $row; + foreach($objarray as $key => $value) { + $this->attributes[$key] = $value; } + + return true; } /** - * Return the object specific details of a object by a row. - * - * @param int $guid + * Override the save function. + * @return true|false */ - function get_object_entity_as_row($guid) - { - global $CONFIG; - - $guid = (int)$guid; - - /*$row = retrieve_cached_entity_row($guid); - if ($row) - { - // We have already cached this object, so retrieve its value from the cache - if (isset($CONFIG->debug) && $CONFIG->debug) - error_log("** Retrieving sub part of GUID:$guid from cache"); - - return $row; + public function save() { + // Save generic stuff + if (!parent::save()) { + return false; } - else - {*/ - // Object not cached, load it. - if ($CONFIG->debug) - error_log("** Sub part of GUID:$guid loaded from DB"); - - return get_data_row("SELECT * from {$CONFIG->dbprefix}objects_entity where guid=$guid"); - //} + + // Now save specific stuff + return create_object_entity($this->get('guid'), $this->get('title'), $this->get('description'), $this->get('container_guid')); } - + /** - * Create or update the extras table for a given object. - * Call create_entity first. - * - * @param int $guid The guid of the entity you're creating (as obtained by create_entity) - * @param string $title The title of the object - * @param string $description The object's description + * Get sites that this object is a member of + * + * @param string $subtype Optionally, the subtype of result we want to limit to + * @param int $limit The number of results to return + * @param int $offset Any indexing offset */ - function create_object_entity($guid, $title, $description) - { - global $CONFIG; - - $guid = (int)$guid; - $title = sanitise_string($title); - $description = sanitise_string($description); - - $row = get_entity_as_row($guid); - - if ($row) - { - // Core entities row exists and we have access to it - if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}objects_entity where guid = {$guid}")) { - $result = update_data("UPDATE {$CONFIG->dbprefix}objects_entity set title='$title', description='$description' where guid=$guid"); - if ($result!=false) - { - // Update succeeded, continue - $entity = get_entity($guid); - if (trigger_elgg_event('update',$entity->type,$entity)) { - return $guid; - } else { - $entity->delete(); - } - } - } - else - { - - // Update failed, attempt an insert. - $result = insert_data("INSERT into {$CONFIG->dbprefix}objects_entity (guid, title, description) values ($guid, '$title','$description')"); - if ($result!==false) { - $entity = get_entity($guid); - if (trigger_elgg_event('create',$entity->type,$entity)) { - return $guid; - } else { - $entity->delete(); - //delete_entity($guid); - } - } - } - - } - - return false; + function getSites($subtype="", $limit = 10, $offset = 0) { + return get_site_objects($this->getGUID(), $subtype, $limit, $offset); } - + /** - * THIS FUNCTION IS DEPRECATED. - * - * Delete a object's extra data. - * - * @param int $guid + * Add this object to a particular site + * + * @param int $site_guid The guid of the site to add it to + * @return true|false */ - function delete_object_entity($guid) - { - system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity')); - - return 1; // Always return that we have deleted one row in order to not break existing code. + function addToSite($site_guid) { + return add_site_object($this->getGUID(), $site_guid); } - + /** - * Searches for an object based on a complete or partial title or description using full text searching. - * - * IMPORTANT NOTE: With MySQL's default setup: - * 1) $criteria must be 4 or more characters long - * 2) If $criteria matches greater than 50% of results NO RESULTS ARE RETURNED! + * Set the container for this object. * - * @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. + * @param int $container_guid The ID of the container. + * @return bool */ - function search_for_object($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) - { - global $CONFIG; - - $criteria = sanitise_string($criteria); - $limit = (int)$limit; - $offset = (int)$offset; - $order_by = sanitise_string($order_by); + function setContainer($container_guid) { $container_guid = (int)$container_guid; - - $access = get_access_sql_suffix("e"); - - 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 join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where match(o.title,o.description) against ('$criteria') and $access"; - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); - } else { - if ($count = get_data_row($query)) { - return $count->total; - } + + return $this->set('container_guid', $container_guid); + } + + /** + * Return the container GUID of this object. + * + * @return int + */ + function getContainer() { + return $this->get('container_guid'); + } + + /** + * As getContainer(), but returns the whole entity. + * + * @return mixed ElggGroup object or false. + */ + function getContainerEntity() { + $result = get_entity($this->getContainer()); + + if (($result) && ($result instanceof ElggGroup)) { + return $result; } + return false; } /** - * Get the sites this object is part of + * Get the collections associated with a object. * - * @param int $object_guid The object's GUID - * @param int $limit Number of results to return + * @param string $subtype Optionally, the subtype of result we want to limit to + * @param int $limit The number of results to return * @param int $offset Any indexing offset - * @return false|array On success, an array of ElggSites + * @return unknown */ - function get_object_sites($object_guid, $limit = 10, $offset = 0) { - $object_guid = (int)$object_guid; - $limit = (int)$limit; - $offset = (int)$offset; - - return get_entities_from_relationship("member_of_site", $object_guid, false, "site", "", 0, "time_created desc", $limit, $offset); + //public function getCollections($subtype="", $limit = 10, $offset = 0) { get_object_collections($this->getGUID(), $subtype, $limit, $offset); } + + // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// + + /** + * Return an array of fields which can be exported. + */ + public function getExportableValues() { + return array_merge(parent::getExportableValues(), array( + 'title', + 'description', + )); + } +} + +/** + * Return the object specific details of a object by a row. + * + * @param int $guid + */ +function get_object_entity_as_row($guid) { + global $CONFIG; + + $guid = (int)$guid; + + /*$row = retrieve_cached_entity_row($guid); + if ($row) + { + // We have already cached this object, so retrieve its value from the cache + if (isset($CONFIG->debug) && $CONFIG->debug) + error_log("** Retrieving sub part of GUID:$guid from cache"); + + return $row; + } + else + {*/ + // Object not cached, load it. + if ($CONFIG->debug) { + error_log("** Sub part of GUID:$guid loaded from DB"); + } + + return get_data_row("SELECT * from {$CONFIG->dbprefix}objects_entity where guid=$guid"); + //} +} + +/** + * Create or update the extras table for a given object. + * Call create_entity first. + * + * @param int $guid The guid of the entity you're creating (as obtained by create_entity) + * @param string $title The title of the object + * @param string $description The object's description + */ +function create_object_entity($guid, $title, $description) { + global $CONFIG; + + $guid = (int)$guid; + $title = sanitise_string($title); + $description = sanitise_string($description); + + $row = get_entity_as_row($guid); + + if ($row) { + // Core entities row exists and we have access to it + if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}objects_entity where guid = {$guid}")) { + $result = update_data("UPDATE {$CONFIG->dbprefix}objects_entity set title='$title', description='$description' where guid=$guid"); + if ($result!=false) { + // Update succeeded, continue + $entity = get_entity($guid); + if (trigger_elgg_event('update',$entity->type,$entity)) { + return $guid; + } else { + $entity->delete(); + } + } + } else { + // Update failed, attempt an insert. + $result = insert_data("INSERT into {$CONFIG->dbprefix}objects_entity (guid, title, description) values ($guid, '$title','$description')"); + if ($result!==false) { + $entity = get_entity($guid); + if (trigger_elgg_event('create',$entity->type,$entity)) { + return $guid; + } else { + $entity->delete(); + //delete_entity($guid); + } + } + } } + return false; +} + +/** + * THIS FUNCTION IS DEPRECATED. + * + * Delete a object's extra data. + * + * @param int $guid + */ +function delete_object_entity($guid) { + system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity')); + + return 1; // Always return that we have deleted one row in order to not break existing code. +} + +/** + * Searches for an object based on a complete or partial title or description using full text searching. + * + * IMPORTANT NOTE: With MySQL's default setup: + * 1) $criteria must be 4 or more characters long + * 2) If $criteria matches greater than 50% of results NO RESULTS ARE RETURNED! + * + * @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. + */ +function search_for_object($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) { + global $CONFIG; + + $criteria = sanitise_string($criteria); + $limit = (int)$limit; + $offset = (int)$offset; + $order_by = sanitise_string($order_by); + $container_guid = (int)$container_guid; + + $access = get_access_sql_suffix("e"); + + 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 join {$CONFIG->dbprefix}objects_entity o on e.guid=o.guid where match(o.title,o.description) against ('$criteria') and $access"; + + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; + } + } + return false; +} + +/** + * Get the sites this object is part of + * + * @param int $object_guid The object's GUID + * @param int $limit Number of results to return + * @param int $offset Any indexing offset + * @return false|array On success, an array of ElggSites + */ +function get_object_sites($object_guid, $limit = 10, $offset = 0) { + $object_guid = (int)$object_guid; + $limit = (int)$limit; + $offset = (int)$offset; + + return get_entities_from_relationship("member_of_site", $object_guid, false, "site", "", 0, "time_created desc", $limit, $offset); +} + /** * Runs unit tests for ElggObject */ register_plugin_hook('unit_test', 'system', 'objects_test'); + function objects_test($hook, $type, $value, $params) { global $CONFIG; $value[] = "{$CONFIG->path}engine/tests/objects/objects.php"; return $value; -} +} \ No newline at end of file diff --git a/engine/lib/opendd.php b/engine/lib/opendd.php index 4917120fd..16d5b4671 100644 --- a/engine/lib/opendd.php +++ b/engine/lib/opendd.php @@ -1,372 +1,385 @@ elements = $elements; - else - $this->addElement($elements); - } - else - $this->elements = array(); - } - - /** - * Return the version of ODD being used. - * - * @return string - */ - public function getVersion() { return $this->ODDSupportedVersion; } - - public function getNumElements() { return count($this->elements); } - - public function addElement(ODD $element) { if (!is_array($this->elements)) $this->elements = array(); $this->elements[] = $element; } - public function addElements(array $elements) - { - foreach ($elements as $element) - $this->addElement($element); - } - - public function getElements() { return $this->elements; } - - /** - * Set an optional wrapper factory to optionally embed the ODD document in another format. - */ - public function setWrapperFactory(ODDWrapperFactory $factory) { $this->wrapperfactory = $factory; } - - /** - * Magic function to generate valid ODD XML for this item. - */ - public function __toString() - { - $xml = ""; - - if ($this->wrapperfactory) - { - // A wrapper has been provided - $wrapper = $this->wrapperfactory->getElementWrapper($this); // Get the wrapper for this element - - $xml = $wrapper->wrap($this); // Wrap this element (and subelements) - } - else - { - // Output begin tag - $generated = date("r"); - $xml .= "ODDSupportedVersion}\" generated=\"$generated\">\n"; - - // Get XML for elements - foreach ($this->elements as $element) - $xml .= "$element"; - - // Output end tag - $xml .= "\n"; + private $elements; + + /** + * Optional wrapper factory. + */ + private $wrapperfactory; + + public function __construct(array $elements = NULL) { + if ($elements) { + if (is_array($elements)) { + $this->elements = $elements; + } else { + $this->addElement($elements); } - - return $xml; + } else { + $this->elements = array(); } - - // ITERATOR INTERFACE ////////////////////////////////////////////////////////////// - /* - * This lets an entity's attributes be displayed using foreach as a normal array. - * Example: http://www.sitepoint.com/print/php5-standard-library - */ - - private $valid = FALSE; - - function rewind() - { - $this->valid = (FALSE !== reset($this->elements)); - } - - function current() - { - return current($this->elements); - } - - function key() - { - return key($this->elements); - } - - function next() - { - $this->valid = (FALSE !== next($this->elements)); - } - - function valid() - { - return $this->valid; - } } - + /** - * Open Data Definition (ODD) superclass. - * @package Elgg - * @subpackage Core - * @author Curverider Ltd + * Return the version of ODD being used. + * + * @return string */ - abstract class ODD - { - /** - * Attributes. - */ - private $attributes = array(); - - /** - * Optional body. - */ - private $body; - - /** - * Construct an ODD document with initial values. - */ - public function __construct() - { - $this->body = ""; - } - - public function getAttributes() { return $this->attributes; } - public function setAttribute($key, $value) { $this->attributes[$key] = $value; } - public function getAttribute($key) - { - if (isset($this->attributes[$key])) - return $this->attributes[$key]; - - return NULL; - } - public function setBody($value) { $this->body = $value; } - public function getBody() { return $this->body; } - - /** - * Set the published time. - * - * @param int $time Unix timestamp - */ - public function setPublished($time) - { - $this->attributes['published'] = date("r", $time); + public function getVersion() { + return $this->ODDSupportedVersion; + } + + public function getNumElements() { + return count($this->elements); + } + + public function addElement(ODD $element) { + if (!is_array($this->elements)) { + $this->elements = array(); + $this->elements[] = $element; } - - /** - * Return the published time as a unix timestamp. - * - * @return int or false on failure. - */ - public function getPublishedAsTime() { return strtotime($this->attributes['published']); } - - /** - * For serialisation, implement to return a string name of the tag eg "header" or "metadata". - * @return string - */ - abstract protected function getTagName(); - - /** - * Magic function to generate valid ODD XML for this item. - */ - public function __toString() - { - // Construct attributes - $attr = ""; - foreach ($this->attributes as $k => $v) - $attr .= ($v!="") ? "$k=\"$v\" " : ""; - - $body = $this->getBody(); - $tag = $this->getTagName(); - - $end = "/>"; - if ($body!="") - $end = ">"; - - return "<{$tag} $attr" . $end . "\n"; + } + + public function addElements(array $elements) { + foreach ($elements as $element) { + $this->addElement($element); } - } - + + public function getElements() { + return $this->elements; + } + /** - * ODD Entity class. - * @package Elgg - * @subpackage Core - * @author Curverider Ltd + * Set an optional wrapper factory to optionally embed the ODD document in another format. */ - class ODDEntity extends ODD - { - function __construct($uuid, $class, $subclass = "") - { - parent::__construct(); - - $this->setAttribute('uuid', $uuid); - $this->setAttribute('class', $class); - $this->setAttribute('subclass', $subclass); - } - - protected function getTagName() { return "entity"; } + public function setWrapperFactory(ODDWrapperFactory $factory) { + $this->wrapperfactory = $factory; } - + /** - * ODD Metadata class. - * @package Elgg - * @subpackage Core - * @author Curverider Ltd + * Magic function to generate valid ODD XML for this item. */ - class ODDMetaData extends ODD - { - function __construct($uuid, $entity_uuid, $name, $value, $type = "", $owner_uuid = "") - { - parent::__construct(); - - $this->setAttribute('uuid', $uuid); - $this->setAttribute('entity_uuid', $entity_uuid); - $this->setAttribute('name', $name); - $this->setAttribute('type', $type); - $this->setAttribute('owner_uuid', $owner_uuid); - $this->setBody($value); + public function __toString() { + $xml = ""; + + if ($this->wrapperfactory) { + // A wrapper has been provided + $wrapper = $this->wrapperfactory->getElementWrapper($this); // Get the wrapper for this element + + $xml = $wrapper->wrap($this); // Wrap this element (and subelements) + } else { + // Output begin tag + $generated = date("r"); + $xml .= "ODDSupportedVersion}\" generated=\"$generated\">\n"; + + // Get XML for elements + foreach ($this->elements as $element) { + $xml .= "$element"; + } + + // Output end tag + $xml .= "\n"; } - - protected function getTagName() { return "metadata"; } + + return $xml; } - - /** - * ODD Relationship class. - * @package Elgg - * @subpackage Core - * @author Curverider Ltd + + // ITERATOR INTERFACE ////////////////////////////////////////////////////////////// + /* + * This lets an entity's attributes be displayed using foreach as a normal array. + * Example: http://www.sitepoint.com/print/php5-standard-library */ - class ODDRelationship extends ODD - { - function __construct($uuid1, $type, $uuid2) - { - parent::__construct(); - - $this->setAttribute('uuid1', $uuid1); - $this->setAttribute('type', $type); - $this->setAttribute('uuid2', $uuid2); - } - - protected function getTagName() { return "relationship"; } + + private $valid = FALSE; + + function rewind() { + $this->valid = (FALSE !== reset($this->elements)); } - + + function current() { + return current($this->elements); + } + + function key() { + return key($this->elements); + } + + function next() { + $this->valid = (FALSE !== next($this->elements)); + } + + function valid() { + return $this->valid; + } +} + +/** + * Open Data Definition (ODD) superclass. + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + */ +abstract class ODD { /** - * Attempt to construct an ODD object out of a XmlElement or sub-elements. - * - * @param XmlElement $element The element(s) - * @return mixed An ODD object if the element can be handled, or false. + * Attributes. */ - function ODD_factory(XmlElement $element) - { - $name = $element->name; - $odd = false; - - switch ($name) - { - case 'entity' : $odd = new ODDEntity("","",""); break; - case 'metadata' : $odd = new ODDMetaData("","","",""); break; - case 'relationship' : $odd = new ODDRelationship("","",""); break; - } - - // Now populate values - if ($odd) - { - // Attributes - foreach ($element->attributes as $k => $v) - $odd->setAttribute($k,$v); - - // Body - $body = $element->content; - $a = stripos($body, ""); - if (($body) && ($a!==false) && ($b!==false)) - $body = substr($body, $a+8, $b-($a+8)); - - $odd->setBody($body); + private $attributes = array(); + + /** + * Optional body. + */ + private $body; + + /** + * Construct an ODD document with initial values. + */ + public function __construct() { + $this->body = ""; + } + + public function getAttributes() { + return $this->attributes; + } + + public function setAttribute($key, $value) { + $this->attributes[$key] = $value; + } + + public function getAttribute($key) { + if (isset($this->attributes[$key])) { + return $this->attributes[$key]; } - - return $odd; + + return NULL; + } + + public function setBody($value) { + $this->body = $value; } - + + public function getBody() { + return $this->body; + } + /** - * Import an ODD document. - * - * @param string $xml The XML ODD. - * @return ODDDocument + * Set the published time. + * + * @param int $time Unix timestamp */ - function ODD_Import($xml) - { - // Parse XML to an array - $elements = xml_2_object($xml); - - // Sanity check 1, was this actually XML? - if ((!$elements) || (!$elements->children)) - return false; - - // Create ODDDocument - $document = new ODDDocument(); - - // Itterate through array of elements and construct ODD document - $cnt = 0; - - foreach ($elements->children as $child) - { - $odd = ODD_factory($child); - - if ($odd) { - $document->addElement($odd); - $cnt++; - } - } - - // Check that we actually found something - if ($cnt == 0) - return false; - - return $document; + public function setPublished($time) { + $this->attributes['published'] = date("r", $time); } - + /** - * Export an ODD Document. + * Return the published time as a unix timestamp. * - * @param ODDDocument $document The Document. - * @param ODDWrapperFactory $wrapper Optional wrapper permitting the export process to embed ODD in other document formats. + * @return int or false on failure. + */ + public function getPublishedAsTime() { + return strtotime($this->attributes['published']); + } + + /** + * For serialisation, implement to return a string name of the tag eg "header" or "metadata". + * @return string */ - function ODD_Export(ODDDocument $document) - { - return "$document"; + abstract protected function getTagName(); + + /** + * Magic function to generate valid ODD XML for this item. + */ + public function __toString() { + // Construct attributes + $attr = ""; + foreach ($this->attributes as $k => $v) { + $attr .= ($v!="") ? "$k=\"$v\" " : ""; + } + + $body = $this->getBody(); + $tag = $this->getTagName(); + + $end = "/>"; + if ($body!="") { + $end = ">"; + } + + return "<{$tag} $attr" . $end . "\n"; + } +} + +/** + * ODD Entity class. + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + */ +class ODDEntity extends ODD { + function __construct($uuid, $class, $subclass = "") { + parent::__construct(); + + $this->setAttribute('uuid', $uuid); + $this->setAttribute('class', $class); + $this->setAttribute('subclass', $subclass); + } + + protected function getTagName() { return "entity"; } +} + +/** + * ODD Metadata class. + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + */ +class ODDMetaData extends ODD { + function __construct($uuid, $entity_uuid, $name, $value, $type = "", $owner_uuid = "") { + parent::__construct(); + + $this->setAttribute('uuid', $uuid); + $this->setAttribute('entity_uuid', $entity_uuid); + $this->setAttribute('name', $name); + $this->setAttribute('type', $type); + $this->setAttribute('owner_uuid', $owner_uuid); + $this->setBody($value); } - -?> \ No newline at end of file + + protected function getTagName() { + return "metadata"; + } +} + +/** + * ODD Relationship class. + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + */ +class ODDRelationship extends ODD { + function __construct($uuid1, $type, $uuid2) { + parent::__construct(); + + $this->setAttribute('uuid1', $uuid1); + $this->setAttribute('type', $type); + $this->setAttribute('uuid2', $uuid2); + } + + protected function getTagName() { return "relationship"; } +} + +/** + * Attempt to construct an ODD object out of a XmlElement or sub-elements. + * + * @param XmlElement $element The element(s) + * @return mixed An ODD object if the element can be handled, or false. + */ +function ODD_factory(XmlElement $element) { + $name = $element->name; + $odd = false; + + switch ($name) { + case 'entity' : + $odd = new ODDEntity("","",""); + break; + case 'metadata' : + $odd = new ODDMetaData("","","",""); + break; + case 'relationship' : + $odd = new ODDRelationship("","",""); + break; + } + + // Now populate values + if ($odd) { + // Attributes + foreach ($element->attributes as $k => $v) { + $odd->setAttribute($k,$v); + } + + // Body + $body = $element->content; + $a = stripos($body, ""); + if (($body) && ($a!==false) && ($b!==false)) { + $body = substr($body, $a+8, $b-($a+8)); + } + + $odd->setBody($body); + } + + return $odd; +} + +/** + * Import an ODD document. + * + * @param string $xml The XML ODD. + * @return ODDDocument + */ +function ODD_Import($xml) { + // Parse XML to an array + $elements = xml_2_object($xml); + + // Sanity check 1, was this actually XML? + if ((!$elements) || (!$elements->children)) { + return false; + } + + // Create ODDDocument + $document = new ODDDocument(); + + // Itterate through array of elements and construct ODD document + $cnt = 0; + + foreach ($elements->children as $child) { + $odd = ODD_factory($child); + + if ($odd) { + $document->addElement($odd); + $cnt++; + } + } + + // Check that we actually found something + if ($cnt == 0) { + return false; + } + + return $document; +} + +/** + * Export an ODD Document. + * + * @param ODDDocument $document The Document. + * @param ODDWrapperFactory $wrapper Optional wrapper permitting the export process to embed ODD in other document formats. + */ +function ODD_Export(ODDDocument $document) { + return "$document"; +} \ No newline at end of file diff --git a/engine/lib/pagehandler.php b/engine/lib/pagehandler.php index e602590b3..528be81de 100644 --- a/engine/lib/pagehandler.php +++ b/engine/lib/pagehandler.php @@ -1,120 +1,116 @@ $val) { - set_input($name, $val); - } - } - } - $page = explode('/',$page); - - if (!isset($CONFIG->pagehandler) || empty($handler)) { - $result = false; - } else if (isset($CONFIG->pagehandler[$handler]) && is_callable($CONFIG->pagehandler[$handler])) { - $function = $CONFIG->pagehandler[$handler]; - $result = $function($page, $handler); - if ($result !== false) { - $result = true; + //parse_url($_SERVER['REQUEST_URI']); + $query = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], '?') + 1); + if (isset($query)) { + parse_str($query, $query_arr); + if (is_array($query_arr)) { + foreach($query_arr as $name => $val) { + set_input($name, $val); } - } else { - $result = false; } - - if (!$result) { - $result = default_page_handler($page, $handler); + } + $page = explode('/',$page); + + if (!isset($CONFIG->pagehandler) || empty($handler)) { + $result = false; + } else if (isset($CONFIG->pagehandler[$handler]) && is_callable($CONFIG->pagehandler[$handler])) { + $function = $CONFIG->pagehandler[$handler]; + $result = $function($page, $handler); + if ($result !== false) { + $result = true; } - if ($result !== false) $result = true; - - return $result; - + } else { + $result = false; } - - /** - * Registers a page handler for a particular identifier - * - * eg, you can register a function called 'blog_page_handler' for handler type 'blog' - * - * Now for all URLs of type http://yoururl/blog/*, the blog_page_handler function will be called. - * The part of the URL marked with * above will be exploded on '/' characters and passed as an - * array to that function, eg: - * - * For the URL http://yoururl/blog/username/friends/: - * blog_page_handler('blog', array('username','friends')); - * - * @param string $handler The page type to handle - * @param string $function Your function name - * @return true|false Depending on success - */ - function register_page_handler($handler, $function) { - - global $CONFIG; - if (!isset($CONFIG->pagehandler)) - $CONFIG->pagehandler = array(); - if (is_callable($function)) { - $CONFIG->pagehandler[$handler] = $function; - return true; - } - return false; - + + if (!$result) { + $result = default_page_handler($page, $handler); + } + if ($result !== false) { + $result = true; } - - /** - * A default page handler that attempts to load the actual file at a given page handler location - * - * @param array $page The page URL elements - * @param string $handler The base handler - * @return true|false Depending on success - */ - function default_page_handler($page, $handler) { - - global $CONFIG; - $script = ""; - - $page = implode('/',$page); - if (($questionmark = strripos($page, '?'))) - $page = substr($page, 0, $questionmark); - $script = str_replace("..","",$script); - $callpath = $CONFIG->path . $handler . "/" . $page; - if (!file_exists($callpath) || is_dir($callpath) || substr_count($callpath,'.php') == 0) { - if (substr($callpath,strlen($callpath) - 1, 1) != "/") - $callpath .= "/"; - $callpath .= "index.php"; - if (!include($callpath)) - return false; - } else { - include($callpath); - } - + return $result; +} + +/** + * Registers a page handler for a particular identifier + * + * eg, you can register a function called 'blog_page_handler' for handler type 'blog' + * + * Now for all URLs of type http://yoururl/blog/*, the blog_page_handler function will be called. + * The part of the URL marked with * above will be exploded on '/' characters and passed as an + * array to that function, eg: + * + * For the URL http://yoururl/blog/username/friends/: + * blog_page_handler('blog', array('username','friends')); + * + * @param string $handler The page type to handle + * @param string $function Your function name + * @return true|false Depending on success + */ +function register_page_handler($handler, $function) { + global $CONFIG; + if (!isset($CONFIG->pagehandler)) { + $CONFIG->pagehandler = array(); + } + if (is_callable($function)) { + $CONFIG->pagehandler[$handler] = $function; return true; - } -?> \ No newline at end of file + return false; +} + +/** + * A default page handler that attempts to load the actual file at a given page handler location + * + * @param array $page The page URL elements + * @param string $handler The base handler + * @return true|false Depending on success + */ +function default_page_handler($page, $handler) { + global $CONFIG; + $script = ""; + + $page = implode('/',$page); + if (($questionmark = strripos($page, '?'))) { + $page = substr($page, 0, $questionmark); + } + $script = str_replace("..","",$script); + $callpath = $CONFIG->path . $handler . "/" . $page; + if (!file_exists($callpath) || is_dir($callpath) || substr_count($callpath,'.php') == 0) { + if (substr($callpath,strlen($callpath) - 1, 1) != "/") { + $callpath .= "/"; + } + $callpath .= "index.php"; + if (!include($callpath)) { + return false; + } + } else { + include($callpath); + } + + return true; +} \ No newline at end of file diff --git a/engine/lib/pageowner.php b/engine/lib/pageowner.php index cc3e2e8a3..825b41d37 100644 --- a/engine/lib/pageowner.php +++ b/engine/lib/pageowner.php @@ -1,186 +1,172 @@ getGUID(); - } - } - if ((!isset($returnval)) && ($user = get_user_by_username($username))) { - $returnval = $user->getGUID(); - } - } - - - if ((!isset($returnval)) && ($owner = get_input("owner_guid"))) { - if ($user = get_entity($owner)) { - $returnval = $user->getGUID(); - } - } - - - if ((!isset($returnval)) && (!empty($CONFIG->page_owner_handlers) && is_array($CONFIG->page_owner_handlers))) { - foreach($CONFIG->page_owner_handlers as $handler) { - if ((!isset($returnval)) && ($guid = $handler())) { - $returnval = $guid; - } - } - } - - if (isset($returnval)) { - - // Check if this is obtainable, forwarding if not. - /* - * If the owner entity has been set, but is inaccessible then we forward to the dashboard. This - * catches a bunch of WSoDs. It doesn't have much of a performance hit since 99.999% of the time the next thing - * a page does after calling this function is to retrieve the owner entity - which is of course cashed. - */ - $owner_entity = get_entity($returnval); - if (!$owner_entity) { - - // Log an error - error_log(sprintf(elgg_echo('pageownerunavailable'), $returnval)); - - // Forward - forward(); - } - - return $returnval; - } - - return 0; - - } - - /** - * Gets the page owner for the current page. - * @uses $CONFIG - * @return ElggUser|false The current page owner (false if none). - */ - function page_owner_entity() { - - global $CONFIG; - $page_owner = page_owner(); - if ($page_owner > 0) - return get_entity($page_owner); - - return false; - //return new ElggDummy(); - } - - /** - * Adds a page owner handler - a function that will - * return the page owner if required - * (Such functions are required to return false if they don't know) - * @uses $CONFIG - * @param string $functionname The name of the function to call - * @return mixed The guid of the owner or false - */ - - function add_page_owner_handler($functionname) { - - global $CONFIG; - if (empty($CONFIG->page_owner_handlers)) { - $CONFIG->page_owner_handlers = array(); - } - if (is_callable($functionname)) { - $CONFIG->page_owner_handlers[] = $functionname; - } - - } - - /** - * Allows a page to manually set a page owner - * - * @param int $entitytoset The GUID of the page owner - * @return int|false Either the page owner we've just set, or false if unset - */ - function set_page_owner($entitytoset = -1) { - - static $entity; - - if (!isset($entity)) $entity = false; - - if ($entitytoset > -1) { - $entity = $entitytoset; - } - - return $entity; - - } - - /** - * Sets the functional context of a page - * - * @param string $context The context of the page - * @return string|false Either the context string, or false on failure - */ - function set_context($context) { - - global $CONFIG; - if (!empty($context)) { - $context = trim($context); - $context = strtolower($context); - $CONFIG->context = $context; - return $context; - } else { - return false; - } - - } - - /** - * Returns the functional context of a page - * - * @return string The context, or 'main' if no context has been provided - */ - function get_context() { - - global $CONFIG; - if (isset($CONFIG->context) && !empty($CONFIG->context)) { - return $CONFIG->context; - } - if ($context = get_plugin_name(true)) { - return $context; - } - return "main"; - - } - - if (defined('context')) { - global $CONFIG; - $CONFIG->context = context; - } - -?> \ No newline at end of file +/** + * Gets the page owner for the current page. + * @uses $CONFIG + * @return int|false The current page owner guid (0 if none). + */ + +function page_owner() { + global $CONFIG; + + $returnval = NULL; + + $setpageowner = set_page_owner(); + if ($setpageowner !== false) { + return $setpageowner; + } + + if ((!isset($returnval)) && ($username = get_input("username"))) { + if (substr_count($username,'group:')) { + preg_match('/group\:([0-9]+)/i',$username,$matches); + $guid = $matches[1]; + if ($entity = get_entity($guid)) { + $returnval = $entity->getGUID(); + } + } + if ((!isset($returnval)) && ($user = get_user_by_username($username))) { + $returnval = $user->getGUID(); + } + } + + + if ((!isset($returnval)) && ($owner = get_input("owner_guid"))) { + if ($user = get_entity($owner)) { + $returnval = $user->getGUID(); + } + } + + + if ((!isset($returnval)) && (!empty($CONFIG->page_owner_handlers) && is_array($CONFIG->page_owner_handlers))) { + foreach($CONFIG->page_owner_handlers as $handler) { + if ((!isset($returnval)) && ($guid = $handler())) { + $returnval = $guid; + } + } + } + + if (isset($returnval)) { + // Check if this is obtainable, forwarding if not. + /* + * If the owner entity has been set, but is inaccessible then we forward to the dashboard. This + * catches a bunch of WSoDs. It doesn't have much of a performance hit since 99.999% of the time the next thing + * a page does after calling this function is to retrieve the owner entity - which is of course cashed. + */ + $owner_entity = get_entity($returnval); + if (!$owner_entity) { + + // Log an error + error_log(sprintf(elgg_echo('pageownerunavailable'), $returnval)); + + // Forward + forward(); + } + + return $returnval; + } + + return 0; +} + +/** + * Gets the page owner for the current page. + * @uses $CONFIG + * @return ElggUser|false The current page owner (false if none). + */ +function page_owner_entity() { + global $CONFIG; + $page_owner = page_owner(); + if ($page_owner > 0) { + return get_entity($page_owner); + } + + return false; +} + +/** + * Adds a page owner handler - a function that will + * return the page owner if required + * (Such functions are required to return false if they don't know) + * @uses $CONFIG + * @param string $functionname The name of the function to call + * @return mixed The guid of the owner or false + */ + +function add_page_owner_handler($functionname) { + global $CONFIG; + if (empty($CONFIG->page_owner_handlers)) { + $CONFIG->page_owner_handlers = array(); + } + if (is_callable($functionname)) { + $CONFIG->page_owner_handlers[] = $functionname; + } +} + +/** + * Allows a page to manually set a page owner + * + * @param int $entitytoset The GUID of the page owner + * @return int|false Either the page owner we've just set, or false if unset + */ +function set_page_owner($entitytoset = -1) { + static $entity; + + if (!isset($entity)) { + $entity = false; + } + + if ($entitytoset > -1) { + $entity = $entitytoset; + } + + return $entity; + +} + +/** + * Sets the functional context of a page + * + * @param string $context The context of the page + * @return string|false Either the context string, or false on failure + */ +function set_context($context) { + global $CONFIG; + if (!empty($context)) { + $context = trim($context); + $context = strtolower($context); + $CONFIG->context = $context; + return $context; + } else { + return false; + } +} + +/** + * Returns the functional context of a page + * + * @return string The context, or 'main' if no context has been provided + */ +function get_context() { + global $CONFIG; + if (isset($CONFIG->context) && !empty($CONFIG->context)) { + return $CONFIG->context; + } + if ($context = get_plugin_name(true)) { + return $context; + } + return "main"; +} + +if (defined('context')) { + global $CONFIG; + $CONFIG->context = context; +} \ No newline at end of file diff --git a/engine/lib/pam.php b/engine/lib/pam.php index efebb45ec..91bf63f7c 100644 --- a/engine/lib/pam.php +++ b/engine/lib/pam.php @@ -1,95 +1,82 @@ handler = $handler; - $_PAM_HANDLERS[$handler]->importance = strtolower($importance); - - return true; - } - - return false; + $_PAM_HANDLERS[$handler]->handler = $handler; + $_PAM_HANDLERS[$handler]->importance = strtolower($importance); + + return true; } - - /** - * Attempt to authenticate. - * This function will go through all registered PAM handlers to see if a user can be authorised. - * - * If $credentials are provided the PAM handler should authenticate using the provided credentials, if - * not then credentials should be prompted for or otherwise retrieved (eg from the HTTP header or $_SESSION). - * - * @param mixed $credentials Mixed PAM handler specific credentials (eg username,password or hmac etc) - * @return bool true if authenticated, false if not. - */ - function pam_authenticate($credentials = NULL) - { - global $_PAM_HANDLERS, $_PAM_HANDLERS_MSG; - - $authenticated = false; - - foreach ($_PAM_HANDLERS as $k => $v) - { - $handler = $v->handler; - $importance = $v->importance; - - try { - // Execute the handler - if ($handler($credentials)) - { - // Explicitly returned true - $_PAM_HANDLERS_MSG[$k] = "Authenticated!"; - $authenticated = true; - } - else - { - $_PAM_HANDLERS_MSG[$k] = "Not Authenticated."; - - // If this is required then abort. - if ($importance == 'required') - return false; - } - } - catch (Exception $e) - { - $_PAM_HANDLERS_MSG[$k] = "$e"; - + return false; +} + +/** + * Attempt to authenticate. + * This function will go through all registered PAM handlers to see if a user can be authorised. + * + * If $credentials are provided the PAM handler should authenticate using the provided credentials, if + * not then credentials should be prompted for or otherwise retrieved (eg from the HTTP header or $_SESSION). + * + * @param mixed $credentials Mixed PAM handler specific credentials (eg username,password or hmac etc) + * @return bool true if authenticated, false if not. + */ +function pam_authenticate($credentials = NULL) { + global $_PAM_HANDLERS, $_PAM_HANDLERS_MSG; + + $authenticated = false; + + foreach ($_PAM_HANDLERS as $k => $v) { + $handler = $v->handler; + $importance = $v->importance; + + try { + // Execute the handler + if ($handler($credentials)) { + // Explicitly returned true + $_PAM_HANDLERS_MSG[$k] = "Authenticated!"; + + $authenticated = true; + } else { + $_PAM_HANDLERS_MSG[$k] = "Not Authenticated."; + // If this is required then abort. - if ($importance == 'required') + if ($importance == 'required') { return false; - } + } + } + } catch (Exception $e) { + $_PAM_HANDLERS_MSG[$k] = "$e"; + + // If this is required then abort. + if ($importance == 'required') { + return false; + } } - - return $authenticated; } - -?> \ No newline at end of file + + return $authenticated; +} \ No newline at end of file diff --git a/engine/lib/ping.php b/engine/lib/ping.php index af42b9a87..b318806a7 100644 --- a/engine/lib/ping.php +++ b/engine/lib/ping.php @@ -1,47 +1,45 @@ guid); - - return send_api_post_call($NOTIFICATION_SERVER, - array( - 'method' => 'elgg.system.ping', - - 'url' => $site->url, - 'version' => $version, - 'release' => $release, - ), - array(), - $export, - 'text/xml' - ); - } -?> \ No newline at end of file +/** + * The api for the pinger. + * TODO: Have this configurable and/or updatable + */ +$NOTIFICATION_SERVER = "http://ping.elgg.org/pg/api/rest/php/"; + + +/** + * Run once and only once. + * + * @param ElggSite $site The site who's information to use + */ +function ping_home(ElggSite $site) { + global $NOTIFICATION_SERVER, $CONFIG; + + // Get version information + $version = get_version(); + $release = get_version(true); + + // Get export + $export = export($site->guid); + + return send_api_post_call($NOTIFICATION_SERVER, + array( + 'method' => 'elgg.system.ping', + + 'url' => $site->url, + 'version' => $version, + 'release' => $release, + ), + array(), + $export, + 'text/xml' + ); +} \ No newline at end of file diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php index 1fcd2d138..d03f60442 100644 --- a/engine/lib/plugins.php +++ b/engine/lib/plugins.php @@ -1,739 +1,727 @@ attributes['subtype'] = "plugin"; - } - - public function __construct($guid = null) - { - parent::__construct($guid); + +/// Cache enabled plugins per page +$ENABLED_PLUGINS_CACHE = NULL; + +/** + * PluginException + * + * A plugin Exception, thrown when an Exception occurs relating to the plugin mechanism. Subclass for specific plugin Exceptions. + * + * @package Elgg + * @subpackage Exceptions + */ +class PluginException extends Exception {} + +/** + * @class ElggPlugin Object representing a plugin's settings for a given site. + * This class is currently a stub, allowing a plugin to saving settings in an object's metadata for each site. + * @author Curverider Ltd + */ +class ElggPlugin extends ElggObject { + protected function initialise_attributes() { + parent::initialise_attributes(); + + $this->attributes['subtype'] = "plugin"; + } + + public function __construct($guid = null) { + parent::__construct($guid); + } + + /** + * Override entity get and sets in order to save data to private data store. + */ + public function get($name) { + // See if its in our base attribute + if (isset($this->attributes[$name])) { + return $this->attributes[$name]; + } + + // No, so see if its in the private data store. + $meta = get_private_setting($this->guid, $name); + if ($meta) { + return $meta; + } + + // Can't find it, so return null + return null; + } + + /** + * Override entity get and sets in order to save data to private data store. + */ + public function set($name, $value) { + if (array_key_exists($name, $this->attributes)) { + // Check that we're not trying to change the guid! + if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) { + return false; } - - /** - * Override entity get and sets in order to save data to private data store. - */ - public function get($name) - { - // See if its in our base attribute - if (isset($this->attributes[$name])) { - return $this->attributes[$name]; + + $this->attributes[$name] = $value; + } else { + return set_private_setting($this->guid, $name, $value); + } + + return true; + } +} + +/** + * Returns a list of plugins to load, in the order that they should be loaded. + * + * @return array List of plugins + */ +function get_plugin_list() { + global $CONFIG; + + if (!empty($CONFIG->pluginlistcache)) { + return $CONFIG->pluginlistcache; + } + + if ($site = get_entity($CONFIG->site_guid)) { + $pluginorder = $site->pluginorder; + if (!empty($pluginorder)) { + $plugins = unserialize($pluginorder); + + $CONFIG->pluginlistcache = $plugins; + return $plugins; + } else { + $plugins = array(); + + if ($handle = opendir($CONFIG->pluginspath)) { + while ($mod = readdir($handle)) { + if (!in_array($mod,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . "/" . $mod)) { + $plugins[] = $mod; + } } - - // No, so see if its in the private data store. - $meta = get_private_setting($this->guid, $name); - if ($meta) - return $meta; - - // Can't find it, so return null - return null; } - /** - * Override entity get and sets in order to save data to private data store. - */ - public function set($name, $value) - { - if (array_key_exists($name, $this->attributes)) - { - // Check that we're not trying to change the guid! - if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) - return false; - - $this->attributes[$name] = $value; + sort($plugins); + + $CONFIG->pluginlistcache = $plugins; + return $plugins; + } + } + + return false; +} + +/** + * Regenerates the list of known plugins and saves it to the current site + * + * Important: You should regenerate simplecache and the viewpath cache after executing this function + * otherwise you may experience view display artifacts. Do this with the following code: + * + * elgg_view_regenerate_simplecache(); + * elgg_filepath_cache_reset(); + * + * @param array $pluginorder Optionally, a list of existing plugins and their orders + * @return array The new list of plugins and their orders + */ +function regenerate_plugin_list($pluginorder = false) { + global $CONFIG; + + $CONFIG->pluginlistcache = null; + + if ($site = get_entity($CONFIG->site_guid)) { + if (empty($pluginorder)) { + $pluginorder = $site->pluginorder; + $pluginorder = unserialize($pluginorder); + } else { + ksort($pluginorder); + } + + if (empty($pluginorder)) { + $pluginorder = array(); + } + + $max = 0; + if (sizeof($pluginorder)) { + foreach($pluginorder as $key => $plugin) { + if (is_dir($CONFIG->pluginspath . "/" . $plugin)) { + if ($key > $max) + $max = $key; + } else { + unset($pluginorder[$key]); } - else - return set_private_setting($this->guid, $name, $value); - - return true; } } - - /** - * Returns a list of plugins to load, in the order that they should be loaded. - * - * @return array List of plugins - */ - function get_plugin_list() { - - global $CONFIG; - - if (!empty($CONFIG->pluginlistcache)) - return $CONFIG->pluginlistcache; - - if ($site = get_entity($CONFIG->site_guid)) { - - $pluginorder = $site->pluginorder; - if (!empty($pluginorder)) { - - $plugins = unserialize($pluginorder); - - $CONFIG->pluginlistcache = $plugins; - return $plugins; - - } else { - - $plugins = array(); - - if ($handle = opendir($CONFIG->pluginspath)) { - while ($mod = readdir($handle)) { - if (!in_array($mod,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . "/" . $mod)) { - $plugins[] = $mod; - } - } + // Add new plugins to the end + if ($handle = opendir($CONFIG->pluginspath)) { + while ($mod = readdir($handle)) { + if (!in_array($mod,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . "/" . $mod)) { + if (!in_array($mod, $pluginorder)) { + $max = $max + 10; + $pluginorder[$max] = $mod; } - - sort($plugins); - - $CONFIG->pluginlistcache = $plugins; - return $plugins; - } - } - - return false; - } - - /** - * Regenerates the list of known plugins and saves it to the current site - * - * Important: You should regenerate simplecache and the viewpath cache after executing this function - * otherwise you may experience view display artifacts. Do this with the following code: - * - * elgg_view_regenerate_simplecache(); - * elgg_filepath_cache_reset(); - * - * @param array $pluginorder Optionally, a list of existing plugins and their orders - * @return array The new list of plugins and their orders - */ - function regenerate_plugin_list($pluginorder = false) { - - global $CONFIG; - - $CONFIG->pluginlistcache = null; - - if ($site = get_entity($CONFIG->site_guid)) { - - if (empty($pluginorder)) { - $pluginorder = $site->pluginorder; - $pluginorder = unserialize($pluginorder); - } else { - ksort($pluginorder); - } - if (empty($pluginorder)) { - $pluginorder = array(); - } - - $max = 0; - if (sizeof($pluginorder)) - foreach($pluginorder as $key => $plugin) { - if (is_dir($CONFIG->pluginspath . "/" . $plugin)) { - if ($key > $max) - $max = $key; - } else { - unset($pluginorder[$key]); - } - } - - // Add new plugins to the end - if ($handle = opendir($CONFIG->pluginspath)) { - while ($mod = readdir($handle)) { - if (!in_array($mod,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . "/" . $mod)) { - if (!in_array($mod, $pluginorder)) { - $max = $max + 10; - $pluginorder[$max] = $mod; - } - } - } - } - - ksort($pluginorder); - - // Now reorder the keys .. - $key = 10; - $plugins = array(); - if (sizeof($pluginorder)) - foreach($pluginorder as $plugin) { - $plugins[$key] = $plugin; - $key = $key + 10; - } - - $plugins = serialize($plugins); - - $site->pluginorder = $plugins; - - // Regenerate caches - elgg_view_regenerate_simplecache(); - elgg_filepath_cache_reset(); - - return $plugins; - + ksort($pluginorder); + + // Now reorder the keys .. + $key = 10; + $plugins = array(); + if (sizeof($pluginorder)) { + foreach($pluginorder as $plugin) { + $plugins[$key] = $plugin; + $key = $key + 10; } - - return false; - } - - - /** - * For now, loads plugins directly - * - * @todo Add proper plugin handler that launches plugins in an admin-defined order and activates them on admin request - * @package Elgg - * @subpackage Core - */ - function load_plugins() { - - global $CONFIG; - - if (!empty($CONFIG->pluginspath)) { - - // See if we have cached values for things - $cached_view_paths = elgg_filepath_cache_load(); - if ($cached_view_paths) $CONFIG->views = unserialize($cached_view_paths); - - // temporary disable all plugins if there is a file called 'disabled' in the plugin dir - if (file_exists($CONFIG->pluginspath . "disabled")) - return; - - $plugins = get_plugin_list(); - - if (sizeof($plugins)) - { - foreach($plugins as $mod) { - if (is_plugin_enabled($mod)) { - if (file_exists($CONFIG->pluginspath . $mod)) { - if (!include($CONFIG->pluginspath . $mod . "/start.php")) - throw new PluginException(sprintf(elgg_echo('PluginException:MisconfiguredPlugin'), $mod)); - - if (!$cached_view_paths) - { - if (is_dir($CONFIG->pluginspath . $mod . "/views")) { - if ($handle = opendir($CONFIG->pluginspath . $mod . "/views")) { - while ($viewtype = readdir($handle)) { - if (!in_array($viewtype,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . $mod . "/views/" . $viewtype)) { - autoregister_views("",$CONFIG->pluginspath . $mod . "/views/" . $viewtype,$CONFIG->pluginspath . $mod . "/views/", $viewtype); - } - } + + $plugins = serialize($plugins); + + $site->pluginorder = $plugins; + + // Regenerate caches + elgg_view_regenerate_simplecache(); + elgg_filepath_cache_reset(); + + return $plugins; + + } + + return false; +} + + +/** + * For now, loads plugins directly + * + * @todo Add proper plugin handler that launches plugins in an admin-defined order and activates them on admin request + * @package Elgg + * @subpackage Core + */ +function load_plugins() { + global $CONFIG; + + if (!empty($CONFIG->pluginspath)) { + // See if we have cached values for things + $cached_view_paths = elgg_filepath_cache_load(); + if ($cached_view_paths) { + $CONFIG->views = unserialize($cached_view_paths); + } + + // temporary disable all plugins if there is a file called 'disabled' in the plugin dir + if (file_exists($CONFIG->pluginspath . "disabled")) { + return; + } + + $plugins = get_plugin_list(); + + if (sizeof($plugins)) { + foreach($plugins as $mod) { + if (is_plugin_enabled($mod)) { + if (file_exists($CONFIG->pluginspath . $mod)) { + if (!include($CONFIG->pluginspath . $mod . "/start.php")) { + throw new PluginException(sprintf(elgg_echo('PluginException:MisconfiguredPlugin'), $mod)); + } + + if (!$cached_view_paths) { + if (is_dir($CONFIG->pluginspath . $mod . "/views")) { + if ($handle = opendir($CONFIG->pluginspath . $mod . "/views")) { + while ($viewtype = readdir($handle)) { + if (!in_array($viewtype,array('.','..','.svn','CVS')) && is_dir($CONFIG->pluginspath . $mod . "/views/" . $viewtype)) { + autoregister_views("",$CONFIG->pluginspath . $mod . "/views/" . $viewtype,$CONFIG->pluginspath . $mod . "/views/", $viewtype); } } } - - if (is_dir($CONFIG->pluginspath . $mod . "/languages")) { - register_translations($CONFIG->pluginspath . $mod . "/languages/"); - } } } - } - } - // Cache results - if (!$cached_view_paths) - elgg_filepath_cache_save(serialize($CONFIG->views)); - } - - } - - /** - * Get the name of the most recent plugin to be called in the call stack (or the plugin that owns the current page, if any). - * - * i.e., if the last plugin was in /mod/foobar/, get_plugin_name would return foo_bar. - * - * @param boolean $mainfilename If set to true, this will instead determine the context from the main script filename called by the browser. Default = false. - * @return string|false Plugin name, or false if no plugin name was called - */ - function get_plugin_name($mainfilename = false) { - if (!$mainfilename) { - if ($backtrace = debug_backtrace()) { - foreach($backtrace as $step) { - $file = $step['file']; - $file = str_replace("\\","/",$file); - $file = str_replace("//","/",$file); - if (preg_match("/mod\/([a-zA-Z0-9\-\_]*)\/start\.php$/",$file,$matches)) { - return $matches[1]; + if (is_dir($CONFIG->pluginspath . $mod . "/languages")) { + register_translations($CONFIG->pluginspath . $mod . "/languages/"); } } } - } else { - //if (substr_count($file,'handlers/pagehandler')) { - if (preg_match("/pg\/([a-zA-Z0-9\-\_]*)\//",$_SERVER['REQUEST_URI'],$matches)) { - return $matches[1]; - } else { - $file = $_SERVER["SCRIPT_NAME"]; - $file = str_replace("\\","/",$file); - $file = str_replace("//","/",$file); - if (preg_match("/mod\/([a-zA-Z0-9\-\_]*)\//",$file,$matches)) { - return $matches[1]; - } - } - } - return false; - } - - /** - * Load and parse a plugin manifest from a plugin XML file. - * - * Example file: - * - * - * - * - * - * - * - * - * - * - * @param string $plugin Plugin name. - * @return array of values - */ - function load_plugin_manifest($plugin) - { - global $CONFIG; - - $xml = xml_2_object(file_get_contents($CONFIG->pluginspath . $plugin. "/manifest.xml")); - - if ($xml) - { - $elements = array(); - - foreach ($xml->children as $element) - { - $key = $element->attributes['key']; - $value = $element->attributes['value']; - - $elements[$key] = $value; - } - - return $elements; - } - - return false; - } - - /** - * This function checks a plugin manifest 'elgg_version' value against the current install - * returning TRUE if the elgg_version is <= the current install's version. - * @param $manifest_elgg_version_string The build version (eg 2009010201). - * @return bool - */ - function check_plugin_compatibility($manifest_elgg_version_string) - { - $version = get_version(); - - if (strpos($manifest_elgg_version_string, '.')===false) - { - // Using version - $req_version = (int)$manifest_elgg_version_string; - - return ($version >= $req_version); } - - return false; } - - /** - * Shorthand function for finding the plugin settings. - * - * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you - * are calling from. - */ - function find_plugin_settings($plugin_name = "") - { - $plugins = get_entities('object', 'plugin', 0, "", 9999); - $plugin_name = sanitise_string($plugin_name); - if (!$plugin_name) - $plugin_name = get_plugin_name(); - - if ($plugins) - { - foreach ($plugins as $plugin) - if (strcmp($plugin->title, $plugin_name)==0) - return $plugin; - } - - return false; + + // Cache results + if (!$cached_view_paths) { + elgg_filepath_cache_save(serialize($CONFIG->views)); } - - /** - * Find the plugin settings for a user. - * - * @param string $plugin_name Plugin name. - * @param int $user_guid The guid who's settings to retrieve. - * @return array of settings in an associative array minus prefix. - */ - function find_plugin_usersettings($plugin_name = "", $user_guid = 0) - { - $plugin_name = sanitise_string($plugin_name); - $user_guid = (int)$user_guid; - - if (!$plugin_name) - $plugin_name = get_plugin_name(); - - if ($user_guid == 0) $user_guid = get_loggedin_userid(); - - // Get metadata for user - $all_metadata = get_all_private_settings($user_guid); //get_metadata_for_entity($user_guid); - if ($all_metadata) - { - $prefix = "plugin:settings:$plugin_name:"; - $return = new stdClass; - - foreach ($all_metadata as $key => $meta) - { - $name = substr($key, strlen($prefix)); - $value = $meta; - - if (strpos($key, $prefix) === 0) - $return->$name = $value; - } + } +} - return $return; +/** + * Get the name of the most recent plugin to be called in the call stack (or the plugin that owns the current page, if any). + * + * i.e., if the last plugin was in /mod/foobar/, get_plugin_name would return foo_bar. + * + * @param boolean $mainfilename If set to true, this will instead determine the context from the main script filename called by the browser. Default = false. + * @return string|false Plugin name, or false if no plugin name was called + */ +function get_plugin_name($mainfilename = false) { + if (!$mainfilename) { + if ($backtrace = debug_backtrace()) { + foreach($backtrace as $step) { + $file = $step['file']; + $file = str_replace("\\","/",$file); + $file = str_replace("//","/",$file); + if (preg_match("/mod\/([a-zA-Z0-9\-\_]*)\/start\.php$/",$file,$matches)) { + return $matches[1]; + } } - - return false; } - - /** - * Set a user specific setting for a plugin. - * - * @param string $name The name - note, can't be "title". - * @param mixed $value The value. - * @param int $user_guid Optional user. - * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. - */ - function set_plugin_usersetting($name, $value, $user_guid = 0, $plugin_name = "") - { - $plugin_name = sanitise_string($plugin_name); - $user_guid = (int)$user_guid; - $name = sanitise_string($name); - - if (!$plugin_name) - $plugin_name = get_plugin_name(); - - $user = get_entity($user_guid); - if (!$user) $user = get_loggedin_user(); - - if (($user) && ($user instanceof ElggUser)) - { - $prefix = "plugin:settings:$plugin_name:$name"; - //$user->$prefix = $value; - //$user->save(); - - // Hook to validate setting - $value = trigger_plugin_hook('plugin:usersetting', 'user', array( - 'user' => $user, - 'plugin' => $plugin_name, - 'name' => $name, - 'value' => $value - ), $value); - - return set_private_setting($user->guid, $prefix, $value); + } else { + //if (substr_count($file,'handlers/pagehandler')) { + if (preg_match("/pg\/([a-zA-Z0-9\-\_]*)\//",$_SERVER['REQUEST_URI'],$matches)) { + return $matches[1]; + } else { + $file = $_SERVER["SCRIPT_NAME"]; + $file = str_replace("\\","/",$file); + $file = str_replace("//","/",$file); + if (preg_match("/mod\/([a-zA-Z0-9\-\_]*)\//",$file,$matches)) { + return $matches[1]; } - - return false; } - - /** - * Get a user specific setting for a plugin. - * - * @param string $name The name. - * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. - */ - function get_plugin_usersetting($name, $user_guid = 0, $plugin_name = "") - { - $plugin_name = sanitise_string($plugin_name); - $user_guid = (int)$user_guid; - $name = sanitise_string($name); - - if (!$plugin_name) - $plugin_name = get_plugin_name(); - - $user = get_entity($user_guid); - if (!$user) $user = get_loggedin_user(); - - if (($user) && ($user instanceof ElggUser)) - { - $prefix = "plugin:settings:$plugin_name:$name"; - return get_private_setting($user->guid, $prefix); //$user->$prefix; - } - - return false; + } + return false; +} + +/** + * Load and parse a plugin manifest from a plugin XML file. + * + * Example file: + * + * + * + * + * + * + * + * + * + * + * @param string $plugin Plugin name. + * @return array of values + */ +function load_plugin_manifest($plugin) { + global $CONFIG; + + $xml = xml_2_object(file_get_contents($CONFIG->pluginspath . $plugin. "/manifest.xml")); + + if ($xml) { + $elements = array(); + + foreach ($xml->children as $element) { + $key = $element->attributes['key']; + $value = $element->attributes['value']; + + $elements[$key] = $value; } - - /** - * Set a setting for a plugin. - * - * @param string $name The name - note, can't be "title". - * @param mixed $value The value. - * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. - */ - function set_plugin_setting($name, $value, $plugin_name = "") - { - if (!$plugin_name) $plugin_name = get_plugin_name(); - $plugin = find_plugin_settings($plugin_name); - - if (!$plugin) - $plugin = new ElggPlugin(); - - if ($name!='title') - { - // Hook to validate setting - $value = trigger_plugin_hook('plugin:setting', 'plugin', array( - 'plugin' => $plugin_name, - 'name' => $name, - 'value' => $value - ), $value); - - $plugin->title = $plugin_name; - $plugin->access_id = ACCESS_PUBLIC; - $plugin->save(); - $plugin->$name = $value; - - return $plugin->getGUID(); + + return $elements; + } + + return false; +} + +/** + * This function checks a plugin manifest 'elgg_version' value against the current install + * returning TRUE if the elgg_version is <= the current install's version. + * @param $manifest_elgg_version_string The build version (eg 2009010201). + * @return bool + */ +function check_plugin_compatibility($manifest_elgg_version_string) { + $version = get_version(); + + if (strpos($manifest_elgg_version_string, '.') === false) { + // Using version + $req_version = (int)$manifest_elgg_version_string; + + return ($version >= $req_version); + } + + return false; +} + +/** + * Shorthand function for finding the plugin settings. + * + * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you + * are calling from. + */ +function find_plugin_settings($plugin_name = "") { + $plugins = get_entities('object', 'plugin', 0, "", 9999); + $plugin_name = sanitise_string($plugin_name); + if (!$plugin_name) { + $plugin_name = get_plugin_name(); + } + + if ($plugins) { + foreach ($plugins as $plugin) { + if (strcmp($plugin->title, $plugin_name)==0) { + return $plugin; } - - return false; - } - - /** - * Get setting for a plugin. - * - * @param string $name The name. - * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. - */ - function get_plugin_setting($name, $plugin_name = "") - { - $plugin = find_plugin_settings($plugin_name); - - if ($plugin) - return $plugin->$name; - - return false; - } - - /** - * Clear a plugin setting. - * - * @param string $name The name. - * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. - */ - function clear_plugin_setting($name, $plugin_name = "") - { - $plugin = find_plugin_settings($plugin_name); - - if ($plugin) - return remove_all_private_settings($plugin->guid); //$plugin->clearMetaData($name); - - return false; } - - /** - * Return an array of installed plugins. - */ - function get_installed_plugins() - { - global $CONFIG; - - $installed_plugins = array(); - - if (!empty($CONFIG->pluginspath)) { - - $plugins = get_plugin_list(); - - foreach($plugins as $mod) { - $installed_plugins[$mod] = array(); - $installed_plugins[$mod]['active'] = is_plugin_enabled($mod); - $installed_plugins[$mod]['manifest'] = load_plugin_manifest($mod); - } - + } + + return false; +} + +/** + * Find the plugin settings for a user. + * + * @param string $plugin_name Plugin name. + * @param int $user_guid The guid who's settings to retrieve. + * @return array of settings in an associative array minus prefix. + */ +function find_plugin_usersettings($plugin_name = "", $user_guid = 0) { + $plugin_name = sanitise_string($plugin_name); + $user_guid = (int)$user_guid; + + if (!$plugin_name) { + $plugin_name = get_plugin_name(); + } + + if ($user_guid == 0) { + $user_guid = get_loggedin_userid(); + } + + // Get metadata for user + $all_metadata = get_all_private_settings($user_guid); //get_metadata_for_entity($user_guid); + if ($all_metadata) { + $prefix = "plugin:settings:$plugin_name:"; + $return = new stdClass; + + foreach ($all_metadata as $key => $meta) { + $name = substr($key, strlen($prefix)); + $value = $meta; + + if (strpos($key, $prefix) === 0) { + $return->$name = $value; } - - return $installed_plugins; } - - /** - * Enable a plugin for a site (default current site) - * - * Important: You should regenerate simplecache and the viewpath cache after executing this function - * otherwise you may experience view display artifacts. Do this with the following code: - * - * elgg_view_regenerate_simplecache(); - * elgg_filepath_cache_reset(); - * - * @param string $plugin The plugin name. - * @param int $site_guid The site id, if not specified then this is detected. - */ - function enable_plugin($plugin, $site_guid = 0) - { - global $CONFIG, $ENABLED_PLUGINS_CACHE; - - $plugin = sanitise_string($plugin); - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - $site = get_entity($site_guid); - if (!($site instanceof ElggSite)) - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite")); - - $enabled = $site->getMetaData('enabled_plugins'); - $new_enabled = array(); - if ($enabled) - { - if (!is_array($enabled)) - $new_enabled[] = $enabled; - else - $new_enabled = $enabled; - } - $new_enabled[] = $plugin; - $new_enabled = array_unique($new_enabled); - - $return = $site->setMetaData('enabled_plugins', $new_enabled); - $ENABLED_PLUGINS_CACHE = $new_enabled; - - return $return; + + return $return; + } + + return false; +} + +/** + * Set a user specific setting for a plugin. + * + * @param string $name The name - note, can't be "title". + * @param mixed $value The value. + * @param int $user_guid Optional user. + * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. + */ +function set_plugin_usersetting($name, $value, $user_guid = 0, $plugin_name = "") { + $plugin_name = sanitise_string($plugin_name); + $user_guid = (int)$user_guid; + $name = sanitise_string($name); + + if (!$plugin_name) { + $plugin_name = get_plugin_name(); + } + + $user = get_entity($user_guid); + if (!$user) { + $user = get_loggedin_user(); + } + + if (($user) && ($user instanceof ElggUser)) { + $prefix = "plugin:settings:$plugin_name:$name"; + //$user->$prefix = $value; + //$user->save(); + + // Hook to validate setting + $value = trigger_plugin_hook('plugin:usersetting', 'user', array( + 'user' => $user, + 'plugin' => $plugin_name, + 'name' => $name, + 'value' => $value + ), $value); + + return set_private_setting($user->guid, $prefix, $value); + } + + return false; +} + +/** + * Get a user specific setting for a plugin. + * + * @param string $name The name. + * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. + */ +function get_plugin_usersetting($name, $user_guid = 0, $plugin_name = "") { + $plugin_name = sanitise_string($plugin_name); + $user_guid = (int)$user_guid; + $name = sanitise_string($name); + + if (!$plugin_name) { + $plugin_name = get_plugin_name(); + } + + $user = get_entity($user_guid); + if (!$user) { + $user = get_loggedin_user(); + } + + if (($user) && ($user instanceof ElggUser)) { + $prefix = "plugin:settings:$plugin_name:$name"; + return get_private_setting($user->guid, $prefix); //$user->$prefix; + } + + return false; +} + +/** + * Set a setting for a plugin. + * + * @param string $name The name - note, can't be "title". + * @param mixed $value The value. + * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. + */ +function set_plugin_setting($name, $value, $plugin_name = "") { + if (!$plugin_name) { + $plugin_name = get_plugin_name(); + } + $plugin = find_plugin_settings($plugin_name); + + if (!$plugin) { + $plugin = new ElggPlugin(); + } + + if ($name!='title') { + // Hook to validate setting + $value = trigger_plugin_hook('plugin:setting', 'plugin', array( + 'plugin' => $plugin_name, + 'name' => $name, + 'value' => $value + ), $value); + + $plugin->title = $plugin_name; + $plugin->access_id = ACCESS_PUBLIC; + $plugin->save(); + $plugin->$name = $value; + + return $plugin->getGUID(); + } + + return false; +} + +/** + * Get setting for a plugin. + * + * @param string $name The name. + * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. + */ +function get_plugin_setting($name, $plugin_name = "") { + $plugin = find_plugin_settings($plugin_name); + + if ($plugin) { + return $plugin->$name; + } + + return false; +} + +/** + * Clear a plugin setting. + * + * @param string $name The name. + * @param string $plugin_name Optional plugin name, if not specified then it is detected from where you are calling from. + */ +function clear_plugin_setting($name, $plugin_name = "") { + $plugin = find_plugin_settings($plugin_name); + + if ($plugin) { + //$plugin->clearMetaData($name); + return remove_all_private_settings($plugin->guid); + } + + return false; +} + +/** + * Return an array of installed plugins. + */ +function get_installed_plugins() { + global $CONFIG; + + $installed_plugins = array(); + + if (!empty($CONFIG->pluginspath)) { + $plugins = get_plugin_list(); + + foreach($plugins as $mod) { + $installed_plugins[$mod] = array(); + $installed_plugins[$mod]['active'] = is_plugin_enabled($mod); + $installed_plugins[$mod]['manifest'] = load_plugin_manifest($mod); } - - /** - * Disable a plugin for a site (default current site) - * - * Important: You should regenerate simplecache and the viewpath cache after executing this function - * otherwise you may experience view display artifacts. Do this with the following code: - * - * elgg_view_regenerate_simplecache(); - * elgg_filepath_cache_reset(); - * - * @param string $plugin The plugin name. - * @param int $site_guid The site id, if not specified then this is detected. - */ - function disable_plugin($plugin, $site_guid = 0) - { - global $CONFIG, $ENABLED_PLUGINS_CACHE; - - $plugin = sanitise_string($plugin); - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - $site = get_entity($site_guid); - if (!($site instanceof ElggSite)) - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite")); - - $enabled = $site->getMetaData('enabled_plugins'); - $new_enabled = array(); - - foreach ($enabled as $plug) - if ($plugin != $plug) - $new_enabled[] = $plug; - - $return = $site->setMetaData('enabled_plugins', $new_enabled); - $ENABLED_PLUGINS_CACHE = $new_enabled; - - return $return; + } + + return $installed_plugins; +} + +/** + * Enable a plugin for a site (default current site) + * + * Important: You should regenerate simplecache and the viewpath cache after executing this function + * otherwise you may experience view display artifacts. Do this with the following code: + * + * elgg_view_regenerate_simplecache(); + * elgg_filepath_cache_reset(); + * + * @param string $plugin The plugin name. + * @param int $site_guid The site id, if not specified then this is detected. + */ +function enable_plugin($plugin, $site_guid = 0) { + global $CONFIG, $ENABLED_PLUGINS_CACHE; + + $plugin = sanitise_string($plugin); + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + $site = get_entity($site_guid); + if (!($site instanceof ElggSite)) { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite")); + } + + $enabled = $site->getMetaData('enabled_plugins'); + $new_enabled = array(); + if ($enabled) { + if (!is_array($enabled)) { + $new_enabled[] = $enabled; + } else { + $new_enabled = $enabled; } - - /** - * Return whether a plugin is enabled or not. - * - * @param string $plugin The plugin name. - * @param int $site_guid The site id, if not specified then this is detected. - * @return bool - */ - function is_plugin_enabled($plugin, $site_guid = 0) - { - global $CONFIG, $ENABLED_PLUGINS_CACHE; - - if (!file_exists($CONFIG->pluginspath . $plugin)) return false; - - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - - if (!$ENABLED_PLUGINS_CACHE) { - $site = get_entity($site_guid); - if (!($site instanceof ElggSite)) - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite")); - - $ENABLED_PLUGINS_CACHE = $site->enabled_plugins; - } - - foreach ($ENABLED_PLUGINS_CACHE as $e) - if ($e == $plugin) return true; - - return false; + } + $new_enabled[] = $plugin; + $new_enabled = array_unique($new_enabled); + + $return = $site->setMetaData('enabled_plugins', $new_enabled); + $ENABLED_PLUGINS_CACHE = $new_enabled; + + return $return; +} + +/** + * Disable a plugin for a site (default current site) + * + * Important: You should regenerate simplecache and the viewpath cache after executing this function + * otherwise you may experience view display artifacts. Do this with the following code: + * + * elgg_view_regenerate_simplecache(); + * elgg_filepath_cache_reset(); + * + * @param string $plugin The plugin name. + * @param int $site_guid The site id, if not specified then this is detected. + */ +function disable_plugin($plugin, $site_guid = 0) { + global $CONFIG, $ENABLED_PLUGINS_CACHE; + + $plugin = sanitise_string($plugin); + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + $site = get_entity($site_guid); + if (!($site instanceof ElggSite)) { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite")); + } + + $enabled = $site->getMetaData('enabled_plugins'); + $new_enabled = array(); + + foreach ($enabled as $plug) { + if ($plugin != $plug) { + $new_enabled[] = $plug; } - - /** - * Run once and only once. - */ - function plugin_run_once() - { - // Register a class - add_subtype("object", "plugin", "ElggPlugin"); + } + + $return = $site->setMetaData('enabled_plugins', $new_enabled); + $ENABLED_PLUGINS_CACHE = $new_enabled; + + return $return; +} + +/** + * Return whether a plugin is enabled or not. + * + * @param string $plugin The plugin name. + * @param int $site_guid The site id, if not specified then this is detected. + * @return bool + */ +function is_plugin_enabled($plugin, $site_guid = 0) { + global $CONFIG, $ENABLED_PLUGINS_CACHE; + + if (!file_exists($CONFIG->pluginspath . $plugin)) { + return false; + } + + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + + if (!$ENABLED_PLUGINS_CACHE) { + $site = get_entity($site_guid); + if (!($site instanceof ElggSite)) { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite")); } - - /** - * Initialise the file modules. - * Listens to system boot and registers any appropriate file types and classes - */ - function plugin_init() - { - // Now run this stuff, but only once - run_function_once("plugin_run_once"); - - // Register some actions - register_action("plugins/settings/save", false, "", true); - register_action("plugins/usersettings/save"); - - register_action('admin/plugins/enable', false, "", true); // Enable - register_action('admin/plugins/disable', false, "", true); // Disable - register_action('admin/plugins/enableall', false, "", true); // Enable all - register_action('admin/plugins/disableall', false, "", true); // Disable all - - register_action('admin/plugins/reorder', false, "", true); // Reorder - + + $ENABLED_PLUGINS_CACHE = $site->enabled_plugins; + } + + foreach ($ENABLED_PLUGINS_CACHE as $e) { + if ($e == $plugin) { + return true; } - - // Register a startup event - register_elgg_event_handler('init','system','plugin_init'); -?> \ No newline at end of file + } + + return false; +} + +/** + * Run once and only once. + */ +function plugin_run_once() { + // Register a class + add_subtype("object", "plugin", "ElggPlugin"); +} + +/** + * Initialise the file modules. + * Listens to system boot and registers any appropriate file types and classes + */ +function plugin_init() { + // Now run this stuff, but only once + run_function_once("plugin_run_once"); + + // Register some actions + register_action("plugins/settings/save", false, "", true); + register_action("plugins/usersettings/save"); + + register_action('admin/plugins/enable', false, "", true); // Enable + register_action('admin/plugins/disable', false, "", true); // Disable + register_action('admin/plugins/enableall', false, "", true); // Enable all + register_action('admin/plugins/disableall', false, "", true); // Disable all + + register_action('admin/plugins/reorder', false, "", true); // Reorder +} + +// Register a startup event +register_elgg_event_handler('init','system','plugin_init'); \ No newline at end of file diff --git a/engine/lib/query.php b/engine/lib/query.php index 75b9eddeb..619a2d288 100644 --- a/engine/lib/query.php +++ b/engine/lib/query.php @@ -2,7 +2,7 @@ /** * Elgg database query * Contains a wrapper for performing database queries in a structured way. - * + * * @package Elgg * @subpackage Core * @author Curverider Ltd @@ -16,18 +16,18 @@ * @author Curverider Ltd * @see Query */ - abstract class QueryComponent + abstract class QueryComponent { /** * Associative array of fields and values - */ + */ private $fields; function __construct() { - $this->fields = array(); + $this->fields = array(); } - + /** * Class member get overloading * @@ -37,7 +37,7 @@ function __get($name) { return $this->fields[$name]; } - + /** * Class member set overloading * @@ -47,39 +47,39 @@ */ function __set($name, $value) { $this->fields[$name] = $value; - + return true; - } + } } - + /** * @class SelectFieldQueryComponent Class representing a select field. * This class represents a select field component. * @author Curverider Ltd * @see Query */ - class SelectFieldQueryComponent extends QueryComponent + class SelectFieldQueryComponent extends QueryComponent { /** * Construct a select field component - * + * * @param string $table The table containing the field. * @param string $field The field or "*" */ - function __construct($table, $field) + function __construct($table, $field) { global $CONFIG; - + $this->table = $CONFIG->dbprefix . sanitise_string($table); $this->field = sanitise_string($field); } - - function __toString() + + function __toString() { return "{$this->table}.{$this->field}"; } } - + /** * @class LimitOffsetQueryComponent * Limit and offset clauses of a query. @@ -90,7 +90,7 @@ { /** * Specify a limit and an offset. - * + * * @param int $limit The limit. * @param int $offset The offset. */ @@ -99,13 +99,13 @@ $this->limit = (int)$limit; $this->offset = (int)$offset; } - + function __toString() { return "limit {$this->offset}, {$this->limit}"; } } - + /** * @class OrderQueryComponent * Order the query results. @@ -117,18 +117,18 @@ function __construct($table, $field, $order = "asc") { global $CONFIG; - + $this->table = $CONFIG->dbprefix . sanitise_string($table); $this->field = sanitise_string($field); $this->order = sanitise_string($order); } - + function __toString() { return "order by {$this->table}.{$this->field} {$this->order}"; } } - + /** * @class TableQueryComponent * List of tables to select from or insert into. @@ -140,16 +140,16 @@ function __construct($table) { global $CONFIG; - + $this->table = $CONFIG->dbprefix . sanitise_string($table); } - + function __toString() { return $this->table; } } - + /** * @class AccessControlQueryComponent * Access control component. @@ -160,7 +160,7 @@ { /** * Construct the ACL. - * + * * @param string $acl_table The table where the access control field is. * @param string $acl_field The field containing the access control. * @param string $object_owner_table The table containing the owner information for the stuff you're retrieving. @@ -169,13 +169,13 @@ function __construct($acl_table = "entities", $acl_field = "access_id", $object_owner_table = "entities", $object_owner_id_field = "owner_guid") { global $CONFIG; - + $this->acl_table = $CONFIG->dbprefix . sanitise_string($acl_table); $this->acl_field = sanitise_string($acl_field); $this->object_owner_table = $CONFIG->dbprefix . sanitise_string($object_owner_table); $this->object_owner_id_field = sanitise_string($object_owner_id_field); } - + function __toString() { //$access = get_access_list(); @@ -185,11 +185,11 @@ // $object_owner_id_field = "owner_guid" // TODO: recode get_access_sql_suffix to make it possible to specify alternate field names return "and ".get_access_sql_suffix($this->acl_table); // Add access controls - + //return "and ({$this->acl_table}.{$this->acl_field} in {$access} or ({$this->acl_table}.{$this->acl_field} = 0 and {$this->object_owner_table}.{$this->object_owner_id_field} = {$_SESSION['id']}))"; } } - + /** * @class JoinQueryComponent Join query. * Represents a join query. @@ -202,27 +202,27 @@ * Construct a join query. * @param string $table Table one to join... * @param string $field Field 1 with... - * @param string $table2 Table 2 ... + * @param string $table2 Table 2 ... * @param string $field2 Field... * @param string $operator Using this operator */ - function __construct($table1, $field1, $table2, $field2, $operator = "=") + function __construct($table1, $field1, $table2, $field2, $operator = "=") { global $CONFIG; - + $this->table1 = $CONFIG->dbprefix . sanitise_string($table1); $this->field1 = sanitise_string($field1); $this->table2 = $CONFIG->dbprefix . sanitise_string($table2); $this->field2 = sanitise_string($field2); $this->operator = sanitise_string($operator); } - - function __toString() + + function __toString() { return "join {$this->table2} on {$this->$table}.{$this->$field} {$this->$operator} {$this->$table2}.{$this->$field2}"; } } - + /** * @class SetQueryComponent Set query. * Represents an update set query. @@ -241,21 +241,21 @@ function __construct($table, $field, $value) { global $CONFIG; - - $this->table = $CONFIG->dbprefix . sanitise_string($table); - $this->field = sanitise_string($field); - if (is_numeric($value)) - $this->value = (int)$value; - else - $this->value = "'".sanitise_string($value)."'"; + + $this->table = $CONFIG->dbprefix . sanitise_string($table); + $this->field = sanitise_string($field); + if (is_numeric($value)) + $this->value = (int)$value; + else + $this->value = "'".sanitise_string($value)."'"; } - - function __toString() + + function __toString() { return "{$this->table}.{$this->field}={$this->value}"; } } - + /** * @class WhereQueryComponent * A component of a where query. @@ -266,7 +266,7 @@ { /** * A where query. - * + * * @param string $left_table The table on the left of the operator * @param string $left_field The left field * @param string $operator The operator eg "=" or "<" @@ -277,15 +277,15 @@ function __construct($left_table, $left_field, $operator, $right_table, $right_field, $link_operator = "and") { global $CONFIG; - + $this->link_operator = sanitise_string($link_operator); - $this->left_table = $CONFIG->dbprefix . sanitise_string($left_table); - $this->left_field = sanitise_string($left_field); - $this->operator = sanitise_string($operator); - $this->right_table = $CONFIG->dbprefix . sanitise_string($right_table); - $this->right_field = sanitise_string($right_field); + $this->left_table = $CONFIG->dbprefix . sanitise_string($left_table); + $this->left_field = sanitise_string($left_field); + $this->operator = sanitise_string($operator); + $this->right_table = $CONFIG->dbprefix . sanitise_string($right_table); + $this->right_field = sanitise_string($right_field); } - + /** * Return the SQL without the link operator. */ @@ -293,13 +293,13 @@ { return "{$this->left_table }.{$this->left_field} {$this->operator} {$this->right_table}.{$this->right_field}"; } - - function __toString() + + function __toString() { return "{$this->link_operator} " . $this->toStringNoLink(); } } - + /** * @class WhereStaticQueryComponent * A component of a where query where there is no right hand table, rather a static value. @@ -310,7 +310,7 @@ { /** * A where query. - * + * * @param string $left_table The table on the left of the operator * @param string $left_field The left field * @param string $operator The operator eg "=" or "<" @@ -320,17 +320,17 @@ function __construct($left_table, $left_field, $operator, $value, $link_operator = "and") { global $CONFIG; - + $this->link_operator = sanitise_string($link_operator); - $this->left_table = $CONFIG->dbprefix . sanitise_string($left_table); - $this->left_field = sanitise_string($left_field); - $this->operator = sanitise_string($operator); - if (is_numeric($value)) - $this->value = (int)$value; - else - $this->value = "'".sanitise_string($value)."'"; + $this->left_table = $CONFIG->dbprefix . sanitise_string($left_table); + $this->left_field = sanitise_string($left_field); + $this->operator = sanitise_string($operator); + if (is_numeric($value)) + $this->value = (int)$value; + else + $this->value = "'".sanitise_string($value)."'"; } - + /** * Return the SQL without the link operator. */ @@ -339,7 +339,7 @@ return "{$this->left_table }.{$this->left_field} {$this->operator} {$this->value}"; } } - + /** * @class WhereSetQueryComponent * A where query that may contain other where queries (in brackets). @@ -351,7 +351,7 @@ /** * Construct a subset of wheres. * - * @param array $wheres An array of WhereQueryComponent + * @param array $wheres An array of WhereQueryComponent * @param string $link_operator How this where clause links with the previous clause, eg. "and" "or" */ function __construct(array $wheres, $link_operator = "and") @@ -359,7 +359,7 @@ $this->link_operator = sanitise_string($link_operator); $this->wheres = $wheres; } - + public function toStringNoLink() { $cnt = 0; @@ -367,135 +367,135 @@ foreach ($this->wheres as $where) { if (!($where instanceof WhereQueryComponent)) throw new DatabaseException(elgg_echo('DatabaseException:WhereSetNonQuery')); - + if (!$cnt) $string.= $where->toStringNoLink(); else $string.=" $where "; - - $cnt ++; + + $cnt ++; } $string .= ")"; - + return $string; } } - + /** * @class QueryTypeQueryComponent * What type of query is this? * @author Curverider Ltd * @see Query */ - abstract class QueryTypeQueryComponent extends QueryComponent + abstract class QueryTypeQueryComponent extends QueryComponent { function __toString() { - return $this->query_type; + return $this->query_type; } } - + /** * @class SelectQueryTypeQueryComponent * A select query. * @author Curverider Ltd * @see Query */ - class SelectQueryTypeQueryComponent extends QueryTypeQueryComponent + class SelectQueryTypeQueryComponent extends QueryTypeQueryComponent { - function __construct() + function __construct() { - $this->query_type = "SELECT"; + $this->query_type = "SELECT"; } } - + /** * @class InsertQueryTypeQueryComponent * An insert query. * @author Curverider Ltd * @see Query */ - class InsertQueryTypeQueryComponent extends QueryTypeQueryComponent + class InsertQueryTypeQueryComponent extends QueryTypeQueryComponent { - function __construct() + function __construct() { - $this->query_type = "INSERT INTO"; + $this->query_type = "INSERT INTO"; } } - + /** * @class DeleteQueryTypeQueryComponent * A delete query. * @author Curverider Ltd * @see Query */ - class DeleteQueryTypeQueryComponent extends QueryTypeQueryComponent + class DeleteQueryTypeQueryComponent extends QueryTypeQueryComponent { - function __construct() + function __construct() { - $this->query_type = "DELETE FROM"; + $this->query_type = "DELETE FROM"; } } - + /** * @class UpdateQueryTypeQueryComponent * An update query. * @author Curverider Ltd * @see Query */ - class UpdateQueryTypeQueryComponent extends QueryTypeQueryComponent + class UpdateQueryTypeQueryComponent extends QueryTypeQueryComponent { - function __construct() + function __construct() { - $this->query_type = "UPDATE"; + $this->query_type = "UPDATE"; } } - + /** * @class Query Provides a framework to construct complex queries in a safer environment. - * + * * The usage of this class depends on the type of query you are executing, but the basic idea is to * construct a query out of pluggable classes. - * - * Once constructed SQL can be generated using the toString method, this should happen automatically + * + * Once constructed SQL can be generated using the toString method, this should happen automatically * if you pass the Query object to get_data or similar. - * - * To construct a query, create a new Query() object and begin populating it with the various classes + * + * To construct a query, create a new Query() object and begin populating it with the various classes * that define the various aspects of the query. - * + * * Notes: - * - You do not have to specify things in any particular order, provided you specify all required + * - You do not have to specify things in any particular order, provided you specify all required * components. * - With database tables you do not have to specify your db prefix, this will be added automatically. - * - When constructing your query keep an eye on the error log - any problems will get spit out here. - * Note also that __toString won't let you throw Exceptions (!!!) so these are caught and echoed to + * - When constructing your query keep an eye on the error log - any problems will get spit out here. + * Note also that __toString won't let you throw Exceptions (!!!) so these are caught and echoed to * the log instead. - * - * Here is an example of a select query which requests some data out of the entities table with an + * + * Here is an example of a select query which requests some data out of the entities table with an * order and limit that uses a subset where and some normal where queries: - * + * *
* // Construct the query * $query = new Query(); - * + * * // Say which table we're interested in * $query->addTable(new TableQueryComponent("entities")); - * + * * // What fields are we interested in * $query->addSelectField(new SelectFieldQueryComponent("entities","*")); - * + * * // Add access control (Default access control uses default fields on entities table. * // Note that it will error without something specified here! * $query->setAccessControl(new AccessControlQueryComponent()); - * + * * // Set a limit and offset, may be omitted. * $query->setLimitAndOffset(new LimitOffsetQueryComponent(10,0)); - * + * * // Specify the order, may be omitted * $query->setOrder(new OrderQueryComponent("entities", "subtype", "desc")); - * + * * // Construct a where query - * // + * // * // This demonstrates a WhereSet which lets you have sub wheres, a * // WhereStatic which lets you compare a table field against a value and a * // Where which lets you compare a table/field with another table/field. @@ -507,150 +507,150 @@ * ) * ) * ); - * + * * get_data($query); *
- * + * * @author Curverider Ltd */ class Query { - + /// The limit of the query - private $limit_and_offset; - + private $limit_and_offset; + /// Fields to return on a query private $fields; - + /// Tables to use in a from query private $tables; - + /// Join tables private $joins; - - /// Set values + + /// Set values private $sets; - + /// Where query private $where; - + /// Order by private $order; - + /// The query type private $query_type; - + /// ACL private $access_control; - + /** * Construct query & initialise variables */ - function __construct() + function __construct() { $this->fields = array(); $this->tables = array(); $this->joins = array(); $this->where = array(); $this->sets = array(); - + $this->setQueryType(new SelectQueryTypeQueryComponent()); } - + /** * Add limits and offsets to the query. - * + * * @param LimitOffsetQueryComponent $component The limit and offset. */ public function setLimitAndOffset(LimitOffsetQueryComponent $component) { $this->limit_and_offset = $component; } - + /** * Reset and set the field to the select statement. - * + * * @param SelectFieldQueryComponent $component Table and field component. */ - public function setSelectField(SelectFieldQueryComponent $component) + public function setSelectField(SelectFieldQueryComponent $component) { $this->fields = array(); return $this->addSelectField($component); } - + /** * Add a select field. - * + * * @param SelectFieldQueryComponent $component Add a component. */ public function addSelectField(SelectFieldQueryComponent $component) { $this->fields[] = $component; } - + /** * Add a join to the component. - * + * * @param JoinQueryComponent $component The join. */ public function addJoin(JoinQueryComponent $component) { $this->joins[] = $component; } - + /** * Set a field value in an update or insert statement. - * + * * @param SetQueryComponent $component Fields to set. */ public function addSet(SetQueryComponent $component) { $this->sets[] = $component; } - + /** * Set the query type, i.e. "select", "update", "insert" & "delete". - * + * * @param QueryTypeQueryComponent $component The query type. */ public function setQueryType(QueryTypeQueryComponent $component) { $this->query_type = $component; } - + /** * Attach an order component. - * + * * @param OrderQueryComponent $component The order component. */ public function setOrder(OrderQueryComponent $component) { $this->order = $component; } - + /** * Add a table to the query. - * + * * @param TableQueryComponent $component Table to add. */ public function addTable(TableQueryComponent $component) { $this->tables[] = $component; } - + /** * Add a where clause to the query. - * + * * @param WhereQueryComponent $component The where component */ public function addWhere(WhereQueryComponent $component) { $this->where[] = $component; } - + /** * Set access control. - * + * * @param AccessControlQueryComponent $component Access control. */ public function setAccessControl(AccessControlQueryComponent $component) { $this->access_control = $component; } - + public function __toString() { global $CONFIG; - + $sql = ""; - + try - { + { // Query prefix & fields if (!empty($this->query_type)) { $sql .= "{$this->query_type} "; - + if (!empty($this->fields)) { $fields = ""; - + foreach ($this->fields as $field) - $fields .= "$field"; - + $fields .= "$field"; + $sql .= " $fields from "; } else @@ -658,131 +658,131 @@ } else throw new DatabaseException(elgg_echo('DatabaseException:UnspecifiedQueryType')); - + // Tables - if (!empty($this->tables)) + if (!empty($this->tables)) { - foreach($this->tables as $table) + foreach($this->tables as $table) $sql .= "$table, "; - + $sql = trim($sql, ", "); } else throw new DatabaseException(elgg_echo('DatabaseException:NoTablesSpecified')); - + // Joins on select queries - if ($this->query_type->query_type == 'select') + if ($this->query_type->query_type == 'select') { - if (!empty($this->joins)) - { - foreach($this->joins as $join) + if (!empty($this->joins)) + { + foreach($this->joins as $join) $sql .= "$join "; } } - + // Setting values if ( - ($this->query_type->query_type == 'update') || + ($this->query_type->query_type == 'update') || ($this->query_type->query_type == 'insert') - ) + ) { $sql .= "set "; - + foreach ($this->sets as $set) $sql .= "$set, "; - + $sql = trim($sql, ", ") . " "; } - + // Where if (!empty($this->where)) { $sql .= " where 1 "; - + foreach ($this->where as $where) $sql .= "$where "; } - + // Access control - if (!empty($this->access_control)) + if (!empty($this->access_control)) { - + // Catch missing Where if (empty($this->where)) $sql .= " where 1 "; - + $sql .= "{$this->access_control} "; - } + } else throw new DatabaseException(elgg_echo('DatabaseException:NoACL')); - + // Order by if (!empty($this->order)) $sql .= "{$this->order} "; - + // Limits if (!empty($this->limit_and_offset)) $sql .= "{$this->limit_and_offset} "; - - - + + + } catch (Exception $e) { trigger_error($e, E_USER_WARNING); } - - + + return $sql; } - + } - + /** * @class SimpleQuery A wrapper for Query which provides simple interface for common functions. - * - * This class provides simple interface functions for constructing a (reasonably) standard database + * + * This class provides simple interface functions for constructing a (reasonably) standard database * query. - * + * * The constructor for this class sets a number of defaults, for example sets default access controls * and a limit and offset - to change this then set it manually. - * + * * @author Curverider Ltd * @see Query */ class SimpleQuery extends Query { - function __construct() + function __construct() { parent::__construct(); - + // Set a default query type (select) $this->simpleQueryType(); - + // Set a default access control $this->simpleAccessControl(); - + // Set default limit and offset $this->simpleLimitAndOffset(); } - + /** * Set the query type. - * + * * @param string $type The type of search - available are "select", "update", "delete", "insert". */ public function simpleQueryType($type = "select") { $type = strtolower(sanitise_string($type)); - + switch ($type) { case "insert" : - return $this->setQueryType(InsertQueryTypeQueryComponent()); + return $this->setQueryType(InsertQueryTypeQueryComponent()); break; - case "delete" : + case "delete" : return $this->setQueryType(DeleteQueryTypeQueryComponent()); break; case "update" : - return $this->setQueryType(UpdateQueryTypeQueryComponent()); + return $this->setQueryType(UpdateQueryTypeQueryComponent()); break; default: return $this->setQueryType(SelectQueryTypeQueryComponent()); } @@ -790,50 +790,50 @@ /** * Set a field to query in a select statement. - * + * * @param string $table Table to query. * @param string $field Field in that table. */ public function simpleSelectField($table, $field) { return $this->setSelectField(new SelectFieldQueryComponent($table, $field)); } - + /** * Add a select field to query in a select statement. - * + * * @param string $table Table to query. - * @param string $field Field in that table. + * @param string $field Field in that table. */ public function simpleAddSelectField($table, $field) { return $this->addSelectField(new SelectFieldQueryComponent($table, $field)); } - + /** * Add a set value to an update query. - * + * * @param string $table The table to update. * @param string $field The field in the table. * @param mixed $value The value to set it to. */ public function simpleSet($table, $field, $value) { return $this->addSet(new SetQueryComponent($table, $field, $value)); } - + /** * Add a join to the table. - * + * * @param string $table Table one to join... * @param string $field Field 1 with... - * @param string $table2 Table 2 ... + * @param string $table2 Table 2 ... * @param string $field2 Field... - * @param string $operator Using this operator + * @param string $operator Using this operator */ public function simpleJoin($table1, $field1, $table2, $field2, $operator = "=") { return $this->addJoin(new JoinQueryComponent($table1, $field1, $table2, $field2, $operator)); } - + /** * Add a table to the query. - * + * * @param string $table The table. */ public function simpleTable($table) { return $this->addTable(new TableQueryComponent($table)); } /** * Compare one table/field to another table/field. - * + * * @param string $left_table The table on the left of the operator * @param string $left_field The left field * @param string $operator The operator eg "=" or "<" @@ -842,10 +842,10 @@ * @param string $link_operator How this where clause links with the previous clause, eg. "and" "or" */ public function simpleWhereOnTable($left_table, $left_field, $operator, $right_table, $right_field, $link_operator = "and") { return $this->addWhere(new WhereQueryComponent($left_table, $left_field, $operator, $right_table, $right_field, $link_operator)); } - + /** * Compare one table/field to a value. - * + * * @param string $left_table The table on the left of the operator * @param string $left_field The left field * @param string $operator The operator eg "=" or "<" @@ -853,10 +853,10 @@ * @param string $link_operator How this where clause links with the previous clause, eg. "and" "or" */ public function simpleWhereOnValue($left_table, $left_field, $operator, $value, $link_operator = "and") { return $this->addWhere(new WhereStaticQueryComponent($left_table, $left_field, $operator, $value, $link_operator)); } - + /** * Set access control. - * + * * @param string $acl_table The table where the access control field is. * @param string $acl_field The field containing the access control. * @param string $object_owner_id_field The field in $object_owner_table containing the owner information. @@ -865,26 +865,25 @@ /** * Set the limit and offset. - * + * * @param int $limit The limit. * @param int $offset The offset. */ public function simpleLimitAndOffset($limit = 25, $offset = 0) { return $this->setLimitAndOffset(new LimitOffsetQueryComponent($limit, $offset)); } - + /** * Set the order query. - * + * * @param string $table The table to query * @param string $field The field to query * @param string $order Order the query */ - public function simpleOrder($table, $field, $order = "desc") + public function simpleOrder($table, $field, $order = "desc") { $table = sanitise_string($table); $field = sanitise_string($field); $order = strtolower(sanitise_string($order)); - + return $this->setOrder(new OrderQueryComponent($table, $field, $order)); break; } } -?> \ No newline at end of file diff --git a/engine/lib/relationships.php b/engine/lib/relationships.php index 27a9917ba..22d3c1faa 100644 --- a/engine/lib/relationships.php +++ b/engine/lib/relationships.php @@ -1,1013 +1,1033 @@ + * @link http://elgg.org/ + */ + +/** + * Relationship class. + * + * @author Curverider Ltd + * @package Elgg + * @subpackage Core + */ +class ElggRelationship implements + Importable, + Exportable, + Loggable, // Can events related to this object class be logged + Iterator, // Override foreach behaviour + ArrayAccess // Override for array access + { /** - * Elgg relationships. - * Stub containing relationship functions, making import and export easier. - * - * @package Elgg - * @subpackage Core - * @author Curverider Ltd - * @link http://elgg.org/ + * This contains the site's main properties (id, etc) + * @var array */ + protected $attributes; /** - * Relationship class. - * - * @author Curverider Ltd - * @package Elgg - * @subpackage Core + * Construct a new site object, optionally from a given id value or row. + * + * @param mixed $id */ - class ElggRelationship implements - Importable, - Exportable, - Loggable, // Can events related to this object class be logged - Iterator, // Override foreach behaviour - ArrayAccess // Override for array access - { - /** - * This contains the site's main properties (id, etc) - * @var array - */ - protected $attributes; - - /** - * Construct a new site object, optionally from a given id value or row. - * - * @param mixed $id - */ - function __construct($id = null) - { - $this->attributes = array(); - - if (!empty($id)) { - - if ($id instanceof stdClass) - $relationship = $id; // Create from db row - else - $relationship = get_relationship($id); - - if ($relationship) { - $objarray = (array) $relationship; - foreach($objarray as $key => $value) { - $this->attributes[$key] = $value; - } - } - } - } - - /** - * Class member get overloading - * - * @param string $name - * @return mixed - */ - protected function __get($name) { - if (isset($this->attributes[$name])) - return $this->attributes[$name]; - - return null; - } - - /** - * Class member set overloading - * - * @param string $name - * @param mixed $value - * @return mixed - */ - protected function __set($name, $value) { - $this->attributes[$name] = $value; - return true; - } + function __construct($id = null) { + $this->attributes = array(); - /** - * Save the relationship - * - * @return int the relationship id - */ - public function save() - { - if ($this->id > 0) - { - delete_relationship($this->id); + if (!empty($id)) { + if ($id instanceof stdClass) { + $relationship = $id; // Create from db row + } else { + $relationship = get_relationship($id); } - $this->id = add_entity_relationship($this->guid_one, $this->relationship, $this->guid_two); - if (!$this->id) throw new IOException(sprintf(elgg_new('IOException:UnableToSaveNew'), get_class())); - - return $this->id; - - } - - /** - * Delete a given relationship. - */ - public function delete() - { - return delete_relationship($this->id); - } - - /** - * Get a URL for this relationship. - * - * @return string - */ - public function getURL() - { - return get_relationship_url($this->id); - } - - // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// - - /** - * Return an array of fields which can be exported. - */ - public function getExportableValues() - { - return array( - 'id', - 'guid_one', - 'relationship', - 'guid_two' - ); - } - - /** - * Export this relationship - * - * @return array - */ - public function export() - { - $uuid = get_uuid_from_object($this); - $relationship = new ODDRelationship( - guid_to_uuid($this->guid_one), - $this->relationship, - guid_to_uuid($this->guid_two) - ); - - $relationship->setAttribute('uuid', $uuid); - - return $relationship; - } - - // IMPORTABLE INTERFACE //////////////////////////////////////////////////////////// - - /** - * Import a relationship - * - * @param array $data - * @param int $version - * @return ElggRelationship - * @throws ImportException - */ - public function import(ODD $data) - { - if (!($element instanceof ODDRelationship)) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnexpectedODDClass')); - - $uuid_one = $data->getAttribute('uuid1'); - $uuid_two = $data->getAttribute('uuid2'); - - // See if this entity has already been imported, if so then we need to link to it - $entity1 = get_entity_from_uuid($uuid_one); - $entity2 = get_entity_from_uuid($uuid_two); - if (($entity1) && ($entity2)) - { - // Set the item ID - $this->attributes['guid_one'] = $entity1->getGUID(); - $this->attributes['guid_two'] = $entity2->getGUID(); - - // Map verb to relationship - //$verb = $data->getAttribute('verb'); - //$relationship = get_relationship_from_verb($verb); - $relationship = $data->getAttribute('type'); - - if ($relationship) - { - $this->attributes['relationship'] = $relationship; - // save - $result = $this->save(); - if (!$result) - throw new ImportException(sprintf(elgg_echo('ImportException:ProblemSaving'), get_class())); - - return $this; + if ($relationship) { + $objarray = (array) $relationship; + foreach($objarray as $key => $value) { + $this->attributes[$key] = $value; } } } - - // SYSTEM LOG INTERFACE //////////////////////////////////////////////////////////// - - /** - * Return an identification for the object for storage in the system log. - * This id must be an integer. - * - * @return int - */ - public function getSystemLogID() { return $this->id; } - - /** - * Return the class name of the object. - */ - public function getClassName() { return get_class($this); } - - /** - * For a given ID, return the object associated with it. - * This is used by the river functionality primarily. - * This is useful for checking access permissions etc on objects. - */ - public function getObjectFromID($id) { return get_relationship($id); } - - /** - * Return the GUID of the owner of this object. - */ - public function getObjectOwnerGUID() { return $this->owner_guid; } - - /** - * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc - */ - public function getType() { return 'relationship'; } - - /** - * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type. - */ - public function getSubtype() { return $this->relationship; } - - // ITERATOR INTERFACE ////////////////////////////////////////////////////////////// - /* - * This lets an entity's attributes be displayed using foreach as a normal array. - * Example: http://www.sitepoint.com/print/php5-standard-library - */ - - private $valid = FALSE; - - function rewind() - { - $this->valid = (FALSE !== reset($this->attributes)); - } - - function current() - { - return current($this->attributes); - } - - function key() - { - return key($this->attributes); - } - - function next() - { - $this->valid = (FALSE !== next($this->attributes)); - } - - function valid() - { - return $this->valid; - } - - // ARRAY ACCESS INTERFACE ////////////////////////////////////////////////////////// - /* - * This lets an entity's attributes be accessed like an associative array. - * Example: http://www.sitepoint.com/print/php5-standard-library - */ - - function offsetSet($key, $value) - { - if ( array_key_exists($key, $this->attributes) ) { - $this->attributes[$key] = $value; - } - } - - function offsetGet($key) - { - if ( array_key_exists($key, $this->attributes) ) { - return $this->attributes[$key]; - } - } - - function offsetUnset($key) - { - if ( array_key_exists($key, $this->attributes) ) { - $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects - } - } - - function offsetExists($offset) - { - return array_key_exists($offset, $this->attributes); - } - } - - + } + /** - * Convert a database row to a new ElggRelationship + * Class member get overloading * - * @param stdClass $row - * @return stdClass or ElggMetadata + * @param string $name + * @return mixed */ - function row_to_elggrelationship($row) - { - if (!($row instanceof stdClass)) - return $row; - - return new ElggRelationship($row); + protected function __get($name) { + if (isset($this->attributes[$name])) { + return $this->attributes[$name]; + } + + return null; } - + /** - * Return a relationship. + * Class member set overloading * - * @param int $id + * @param string $name + * @param mixed $value + * @return mixed */ - function get_relationship($id) - { - global $CONFIG; - - $id = (int)$id; - - return row_to_elggrelationship(get_data_row("SELECT * from {$CONFIG->dbprefix}entity_relationships where id=$id")); + protected function __set($name, $value) { + $this->attributes[$name] = $value; + return true; } - + /** - * Delete a specific relationship. + * Save the relationship * - * @param int $id + * @return int the relationship id */ - function delete_relationship($id) - { - global $CONFIG; - - $id = (int)$id; - - $result = delete_data("delete from {$CONFIG->dbprefix}entity_relationships where id=$id"); - - return $result; - } - + public function save() { + if ($this->id > 0) { + delete_relationship($this->id); + } + + $this->id = add_entity_relationship($this->guid_one, $this->relationship, $this->guid_two); + if (!$this->id) { + throw new IOException(sprintf(elgg_new('IOException:UnableToSaveNew'), get_class())); + } + + return $this->id; + } + /** - * Define an arbitrary relationship between two entities. - * This relationship could be a friendship, a group membership or a site membership. - * - * This function lets you make the statement "$guid_one has $relationship with $guid_two". - * - * @param int $guid_one - * @param string $relationship - * @param int $guid_two + * Delete a given relationship. */ - function add_entity_relationship($guid_one, $relationship, $guid_two) - { - global $CONFIG; - - $guid_one = (int)$guid_one; - $relationship = sanitise_string($relationship); - $guid_two = (int)$guid_two; - - // Check for duplicates - if (check_entity_relationship($guid_one, $relationship, $guid_two)) - return false; - - $result = insert_data("INSERT into {$CONFIG->dbprefix}entity_relationships (guid_one, relationship, guid_two) values ($guid_one, '$relationship', $guid_two)"); - - if ($result!==false) { - $obj = get_relationship($result); - if (trigger_elgg_event('create', $relationship, $obj)) { - return true; - } else { - delete_relationship($result); - } - } - - return false; + public function delete() { + return delete_relationship($this->id); } - + /** - * Determine whether or not a relationship between two entities exists and returns the relationship object if it does + * Get a URL for this relationship. * - * @param int $guid_one The GUID of the entity "owning" the relationship - * @param string $relationship The type of relationship - * @param int $guid_two The GUID of the entity the relationship is with - * @return object|false Depending on success + * @return string */ - function check_entity_relationship($guid_one, $relationship, $guid_two) - { - global $CONFIG; - - $guid_one = (int)$guid_one; - $relationship = sanitise_string($relationship); - $guid_two = (int)$guid_two; - - if ($row = get_data_row("SELECT * FROM {$CONFIG->dbprefix}entity_relationships WHERE guid_one=$guid_one AND relationship='$relationship' AND guid_two=$guid_two limit 1")) { - return $row; - } - return false; + public function getURL() { + return get_relationship_url($this->id); } + // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// + /** - * Remove an arbitrary relationship between two entities. - * - * @param int $guid_one - * @param string $relationship - * @param int $guid_two + * Return an array of fields which can be exported. */ - function remove_entity_relationship($guid_one, $relationship, $guid_two) - { - global $CONFIG; - - $guid_one = (int)$guid_one; - $relationship = sanitise_string($relationship); - $guid_two = (int)$guid_two; - - $obj = check_entity_relationship($guid_one, $relationship, $guid_two); - if ($obj == false) return false; - - if (trigger_elgg_event('delete', $relationship, $obj)) { - return delete_data("DELETE from {$CONFIG->dbprefix}entity_relationships where guid_one=$guid_one and relationship='$relationship' and guid_two=$guid_two"); - } else { - return false; - } + public function getExportableValues() { + return array( + 'id', + 'guid_one', + 'relationship', + 'guid_two' + ); } /** - * Removes all arbitrary relationships originating from a particular entity + * Export this relationship * - * @param int $guid_one The GUID of the entity - * @param string $relationship The name of the relationship (optionally) - * @param true|false $inverse Whether we're deleting inverse relationships (default false) - * @param string $type The type of entity to limit this relationship delete to (defaults to all) - * @return true|false Depending on success + * @return array */ - function remove_entity_relationships($guid_one, $relationship = "", $inverse = false, $type = '') { - - global $CONFIG; - - $guid_one = (int) $guid_one; - - if (!empty($relationship)) { - $relationship = sanitise_string($relationship); - $where = "and er.relationship='$relationship'"; - } else { - $where = ""; + public function export() { + $uuid = get_uuid_from_object($this); + $relationship = new ODDRelationship( + guid_to_uuid($this->guid_one), + $this->relationship, + guid_to_uuid($this->guid_two) + ); + + $relationship->setAttribute('uuid', $uuid); + + return $relationship; + } + + // IMPORTABLE INTERFACE //////////////////////////////////////////////////////////// + + /** + * Import a relationship + * + * @param array $data + * @param int $version + * @return ElggRelationship + * @throws ImportException + */ + public function import(ODD $data) { + if (!($element instanceof ODDRelationship)) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnexpectedODDClass')); } - - if (!empty($type)) { - $type = sanitise_string($type); - if (!$inverse) { - $join = " join {$CONFIG->dbprefix}entities e on e.guid = er.guid_two "; - } else { - $join = " join {$CONFIG->dbprefix}entities e on e.guid = er.guid_one "; - $where .= " and "; + + $uuid_one = $data->getAttribute('uuid1'); + $uuid_two = $data->getAttribute('uuid2'); + + // See if this entity has already been imported, if so then we need to link to it + $entity1 = get_entity_from_uuid($uuid_one); + $entity2 = get_entity_from_uuid($uuid_two); + if (($entity1) && ($entity2)) { + // Set the item ID + $this->attributes['guid_one'] = $entity1->getGUID(); + $this->attributes['guid_two'] = $entity2->getGUID(); + + // Map verb to relationship + //$verb = $data->getAttribute('verb'); + //$relationship = get_relationship_from_verb($verb); + $relationship = $data->getAttribute('type'); + + if ($relationship) { + $this->attributes['relationship'] = $relationship; + // save + $result = $this->save(); + if (!$result) { + throw new ImportException(sprintf(elgg_echo('ImportException:ProblemSaving'), get_class())); + } + + return $this; } - $where .= " and e.type = '{$type}' "; - } else { - $join = ""; - } - - if (!$inverse) { - $sql = "DELETE er from {$CONFIG->dbprefix}entity_relationships as er {$join} where guid_one={$guid_one} {$where}"; - return delete_data($sql); - } else { - $sql = "DELETE er from {$CONFIG->dbprefix}entity_relationships as er {$join} where guid_two={$guid_one} {$where}"; - return delete_data($sql); } - } + // SYSTEM LOG INTERFACE //////////////////////////////////////////////////////////// + /** - * Get all the relationships for a given guid. - * - * @param int $guid + * Return an identification for the object for storage in the system log. + * This id must be an integer. + * + * @return int */ - function get_entity_relationships($guid) - { - global $CONFIG; - - $guid = (int)$guid; - - $query = "SELECT * from {$CONFIG->dbprefix}entity_relationships where guid_one=$guid"; - - return get_data($query, "row_to_elggrelationship"); - } - + public function getSystemLogID() { + return $this->id; + } + /** - * Return entities matching a given query joining against a relationship. - * - * @param string $relationship The relationship eg "friends_of" - * @param int $relationship_guid The guid of the entity to use query - * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" - * @param string $type - * @param string $subtype - * @param int $owner_guid - * @param string $order_by - * @param int $limit - * @param int $offset - * @param boolean $count Set to true if you want to count the number of entities instead (default false) - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @return array|int|false An array of entities, or the number of entities, or false on failure + * Return the class name of the object. */ - function get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) - { - global $CONFIG; - - $relationship = sanitise_string($relationship); - $relationship_guid = (int)$relationship_guid; - $inverse_relationship = (bool)$inverse_relationship; - $type = sanitise_string($type); - $subtype = get_subtype_id($type, $subtype); - $owner_guid = (int)$owner_guid; - if ($order_by == "") $order_by = "time_created desc"; - else $order_by = "time_created, {$order_by}"; - $order_by = sanitise_string($order_by); - $limit = (int)$limit; - $offset = (int)$offset; - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - //$access = get_access_list(); - - $where = array(); - - if ($relationship!="") - $where[] = "r.relationship='$relationship'"; - if ($relationship_guid) - $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'"); - if ($type != "") - $where[] = "e.type='$type'"; - if ($subtype) - $where[] = "e.subtype=$subtype"; - if ($owner_guid != "") - $where[] = "e.container_guid='$owner_guid'"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - - // Select what we're joining based on the options - $joinon = "e.guid = r.guid_one"; - if (!$inverse_relationship) - $joinon = "e.guid = r.guid_two"; - - if ($count) { - $query = "SELECT count(distinct e.guid) as total "; - } else { - $query = "SELECT distinct e.* "; - } - $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on $joinon where "; - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); - } else { - if ($count = get_data_row($query)) { - return $count->total; - } - } - return false; - + public function getClassName() { + return get_class($this); } /** - * Returns a viewable list of entities by relationship - * - * @see elgg_view_entity_list - * - * @param string $relationship The relationship eg "friends_of" - * @param int $relationship_guid The guid of the entity to use query - * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" - * @param string $type The type of entity (eg 'object') - * @param string $subtype The entity subtype - * @param int $owner_guid The owner (default: all) - * @param int $limit The number of entities to display on a page - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow gallery view - * @param true|false $pagination Whether to display pagination (default: true) - * @return string The viewable list of entities + * For a given ID, return the object associated with it. + * This is used by the river functionality primarily. + * This is useful for checking access permissions etc on objects. + */ + public function getObjectFromID($id) { + return get_relationship($id); + } + + /** + * Return the GUID of the owner of this object. */ - function list_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $pagination = true) { - - $limit = (int) $limit; - $offset = (int) get_input('offset'); - $count = get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, "", $limit, $offset, true); - $entities = get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, "", $limit, $offset); + public function getObjectOwnerGUID() { + return $this->owner_guid; + } - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); - + /** + * Return a type of the object - eg. object, group, user, relationship, metadata, annotation etc + */ + public function getType() { + return 'relationship'; } /** - * Gets the number of entities by a the number of entities related to them in a particular way. - * This is a good way to get out the users with the most friends, or the groups with the most members. - * - * @param string $relationship The relationship eg "friends_of" - * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true) - * @param string $type The type of entity (default: all) - * @param string $subtype The entity subtype (default: all) - * @param int $owner_guid The owner of the entities (default: none) - * @param int $limit - * @param int $offset - * @param boolean $count Set to true if you want to count the number of entities instead (default false) - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @return array|int|false An array of entities, or the number of entities, or false on failure + * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type. */ - - function get_entities_by_relationship_count($relationship, $inverse_relationship = true, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_guid = 0) { - - global $CONFIG; - - $relationship = sanitise_string($relationship); - $inverse_relationship = (bool)$inverse_relationship; - $type = sanitise_string($type); - if ($subtype AND !$subtype = get_subtype_id($type, $subtype)) - return false; - $owner_guid = (int)$owner_guid; - $order_by = sanitise_string($order_by); - $limit = (int)$limit; - $offset = (int)$offset; - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - //$access = get_access_list(); - - $where = array(); - - if ($relationship!="") - $where[] = "r.relationship='$relationship'"; - if ($inverse_relationship) { - $on = 'e.guid = r.guid_two'; - } else { - $on = 'e.guid = r.guid_one'; + public function getSubtype() { + return $this->relationship; + } + + // ITERATOR INTERFACE ////////////////////////////////////////////////////////////// + /* + * This lets an entity's attributes be displayed using foreach as a normal array. + * Example: http://www.sitepoint.com/print/php5-standard-library + */ + + private $valid = FALSE; + + function rewind() { + $this->valid = (FALSE !== reset($this->attributes)); + } + + function current() { + return current($this->attributes); + } + + function key() { + return key($this->attributes); + } + + function next() { + $this->valid = (FALSE !== next($this->attributes)); + } + + function valid() { + return $this->valid; + } + + // ARRAY ACCESS INTERFACE ////////////////////////////////////////////////////////// + /* + * This lets an entity's attributes be accessed like an associative array. + * Example: http://www.sitepoint.com/print/php5-standard-library + */ + + function offsetSet($key, $value) { + if ( array_key_exists($key, $this->attributes) ) { + $this->attributes[$key] = $value; } - if ($type != "") - $where[] = "e.type='$type'"; - if ($subtype) - $where[] = "e.subtype=$subtype"; - if ($owner_guid != "") - $where[] = "e.container_guid='$owner_guid'"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - - if ($count) { - $query = "SELECT count(distinct e.guid) as total "; - } else { - $query = "SELECT e.*, count(e.guid) as total "; + } + + function offsetGet($key) { + if ( array_key_exists($key, $this->attributes) ) { + return $this->attributes[$key]; } - - $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on {$on} where "; - - if (!empty($where)) - foreach ($where as $w) - $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - - if (!$count) { - $query .= " group by e.guid "; - $query .= " order by total desc limit {$offset}, {$limit}"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); + } + + function offsetUnset($key) { + if ( array_key_exists($key, $this->attributes) ) { + $this->attributes[$key] = ""; // Full unsetting is dangerious for our objects + } + } + + function offsetExists($offset) { + return array_key_exists($offset, $this->attributes); + } +} + + +/** + * Convert a database row to a new ElggRelationship + * + * @param stdClass $row + * @return stdClass or ElggMetadata + */ +function row_to_elggrelationship($row) { + if (!($row instanceof stdClass)) { + return $row; + } + + return new ElggRelationship($row); +} + +/** + * Return a relationship. + * + * @param int $id + */ +function get_relationship($id) { + global $CONFIG; + + $id = (int)$id; + + return row_to_elggrelationship(get_data_row("SELECT * from {$CONFIG->dbprefix}entity_relationships where id=$id")); +} + +/** + * Delete a specific relationship. + * + * @param int $id + */ +function delete_relationship($id) { + global $CONFIG; + + $id = (int)$id; + + $result = delete_data("delete from {$CONFIG->dbprefix}entity_relationships where id=$id"); + + return $result; +} + +/** + * Define an arbitrary relationship between two entities. + * This relationship could be a friendship, a group membership or a site membership. + * + * This function lets you make the statement "$guid_one has $relationship with $guid_two". + * + * @param int $guid_one + * @param string $relationship + * @param int $guid_two + */ +function add_entity_relationship($guid_one, $relationship, $guid_two) { + global $CONFIG; + + $guid_one = (int)$guid_one; + $relationship = sanitise_string($relationship); + $guid_two = (int)$guid_two; + + // Check for duplicates + if (check_entity_relationship($guid_one, $relationship, $guid_two)) { + return false; + } + + $result = insert_data("INSERT into {$CONFIG->dbprefix}entity_relationships (guid_one, relationship, guid_two) values ($guid_one, '$relationship', $guid_two)"); + + if ($result!==false) { + $obj = get_relationship($result); + if (trigger_elgg_event('create', $relationship, $obj)) { + return true; } else { - if ($count = get_data_row($query)) { - return $count->total; - } + delete_relationship($result); } - + } + + return false; +} + +/** + * Determine whether or not a relationship between two entities exists and returns the relationship object if it does + * + * @param int $guid_one The GUID of the entity "owning" the relationship + * @param string $relationship The type of relationship + * @param int $guid_two The GUID of the entity the relationship is with + * @return object|false Depending on success + */ +function check_entity_relationship($guid_one, $relationship, $guid_two) { + global $CONFIG; + + $guid_one = (int)$guid_one; + $relationship = sanitise_string($relationship); + $guid_two = (int)$guid_two; + + if ($row = get_data_row("SELECT * FROM {$CONFIG->dbprefix}entity_relationships WHERE guid_one=$guid_one AND relationship='$relationship' AND guid_two=$guid_two limit 1")) { + return $row; + } + + return false; +} + +/** + * Remove an arbitrary relationship between two entities. + * + * @param int $guid_one + * @param string $relationship + * @param int $guid_two + */ +function remove_entity_relationship($guid_one, $relationship, $guid_two) { + global $CONFIG; + + $guid_one = (int)$guid_one; + $relationship = sanitise_string($relationship); + $guid_two = (int)$guid_two; + + $obj = check_entity_relationship($guid_one, $relationship, $guid_two); + if ($obj == false) { return false; - } - - /** - * Displays a human-readable list of entities - * - * @param string $relationship The relationship eg "friends_of" - * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true) - * @param string $type The type of entity (eg 'object') - * @param string $subtype The entity subtype - * @param int $owner_guid The owner (default: all) - * @param int $limit The number of entities to display on a page - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow gallery view - * @param true|false $pagination Whether to display pagination (default: true) - * @return string The viewable list of entities - */ - - function list_entities_by_relationship_count($relationship, $inverse_relationship = true, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $pagination = true) { - - $limit = (int) $limit; - $offset = (int) get_input('offset'); - $count = get_entities_by_relationship_count($relationship,$inverse_relationship,$type,$subtype,$owner_guid,0,0,true); - $entities = get_entities_by_relationship_count($relationship,$inverse_relationship,$type,$subtype,$owner_guid,$limit,$offset); - - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); - - } - - /** - * Gets the number of entities by a the number of entities related to them in a particular way also constrained by - * metadata - * - * @param string $relationship The relationship eg "friends_of" - * @param int $relationship_guid The guid of the entity to use query - * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true) - * @param String $meta_name The metadata name - * @param String $meta_value The metadata value - * @param string $type The type of entity (default: all) - * @param string $subtype The entity subtype (default: all) - * @param int $owner_guid The owner of the entities (default: none) - * @param int $limit - * @param int $offset - * @param boolean $count Set to true if you want to count the number of entities instead (default false) - * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. - * @return array|int|false An array of entities, or the number of entities, or false on failure - */ - function get_entities_from_relationships_and_meta($relationship, $relationship_guid, $inverse_relationship = false, $meta_name = "", $meta_value = "", $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_guid = 0) - { - - global $CONFIG; - + + if (trigger_elgg_event('delete', $relationship, $obj)) { + return delete_data("DELETE from {$CONFIG->dbprefix}entity_relationships where guid_one=$guid_one and relationship='$relationship' and guid_two=$guid_two"); + } else { + return false; + } +} + +/** + * Removes all arbitrary relationships originating from a particular entity + * + * @param int $guid_one The GUID of the entity + * @param string $relationship The name of the relationship (optionally) + * @param true|false $inverse Whether we're deleting inverse relationships (default false) + * @param string $type The type of entity to limit this relationship delete to (defaults to all) + * @return true|false Depending on success + */ +function remove_entity_relationships($guid_one, $relationship = "", $inverse = false, $type = '') { + global $CONFIG; + + $guid_one = (int) $guid_one; + + if (!empty($relationship)) { $relationship = sanitise_string($relationship); - $inverse_relationship = (bool)$inverse_relationship; - $relationship_guid = (int)$relationship_guid; + $where = "and er.relationship='$relationship'"; + } else { + $where = ""; + } + + if (!empty($type)) { $type = sanitise_string($type); - if ($subtype AND !$subtype = get_subtype_id($type, $subtype)) - return false; - $owner_guid = (int)$owner_guid; - $order_by = sanitise_string($order_by); - $limit = (int)$limit; - $offset = (int)$offset; - $site_guid = (int) $site_guid; - if ($site_guid == 0) - $site_guid = $CONFIG->site_guid; - - $meta_n = get_metastring_id($meta_name); - $meta_v = get_metastring_id($meta_value); - - //$access = get_access_list(); - - $where = array(); - - if ($relationship!="") - $where[] = "r.relationship='$relationship'"; - - $on = "e.guid = r.guid_one"; - if (!$inverse_relationship) - $on = "e.guid = r.guid_two"; - - if ($type != "") - $where[] = "e.type='$type'"; - if ($subtype) - $where[] = "e.subtype=$subtype"; - if ($owner_guid != "") - $where[] = "e.container_guid='$owner_guid'"; - if ($site_guid > 0) - $where[] = "e.site_guid = {$site_guid}"; - if ($relationship_guid) - $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'"); - - - $metajoin = ""; - if (($meta_name!=="") || ($meta_value!=="")) { - $metajoin = " JOIN {$CONFIG->dbprefix}metadata m on e.guid=m.entity_guid"; - - if ($meta_name!=="") - $where[] = "m.name_id='$meta_n'"; - if ($meta_value!=="") - $where[] = "m.value_id='$meta_v'"; - } - - if ($count) { - $query = "SELECT count(distinct e.guid) as total "; + if (!$inverse) { + $join = " join {$CONFIG->dbprefix}entities e on e.guid = er.guid_two "; } else { - $query = "SELECT distinct e.*, count(e.guid) as total "; + $join = " join {$CONFIG->dbprefix}entities e on e.guid = er.guid_one "; + $where .= " and "; } - - $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on {$on} {$metajoin} where "; - - if (!empty($where)) - foreach ($where as $w) + $where .= " and e.type = '{$type}' "; + } else { + $join = ""; + } + + if (!$inverse) { + $sql = "DELETE er from {$CONFIG->dbprefix}entity_relationships as er {$join} where guid_one={$guid_one} {$where}"; + return delete_data($sql); + } else { + $sql = "DELETE er from {$CONFIG->dbprefix}entity_relationships as er {$join} where guid_two={$guid_one} {$where}"; + return delete_data($sql); + } +} + +/** + * Get all the relationships for a given guid. + * + * @param int $guid + */ +function get_entity_relationships($guid) { + global $CONFIG; + + $guid = (int)$guid; + + $query = "SELECT * from {$CONFIG->dbprefix}entity_relationships where guid_one=$guid"; + + return get_data($query, "row_to_elggrelationship"); +} + +/** + * Return entities matching a given query joining against a relationship. + * + * @param string $relationship The relationship eg "friends_of" + * @param int $relationship_guid The guid of the entity to use query + * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" + * @param string $type + * @param string $subtype + * @param int $owner_guid + * @param string $order_by + * @param int $limit + * @param int $offset + * @param boolean $count Set to true if you want to count the number of entities instead (default false) + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @return array|int|false An array of entities, or the number of entities, or false on failure + */ +function get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $order_by = "", $limit = 10, $offset = 0, $count = false, $site_guid = 0) { + global $CONFIG; + + $relationship = sanitise_string($relationship); + $relationship_guid = (int)$relationship_guid; + $inverse_relationship = (bool)$inverse_relationship; + $type = sanitise_string($type); + $subtype = get_subtype_id($type, $subtype); + $owner_guid = (int)$owner_guid; + if ($order_by == "") { + $order_by = "time_created desc"; + } else { + $order_by = "time_created, {$order_by}"; + } + $order_by = sanitise_string($order_by); + $limit = (int)$limit; + $offset = (int)$offset; + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + //$access = get_access_list(); + + $where = array(); + + if ($relationship!="") { + $where[] = "r.relationship='$relationship'"; + } + + if ($relationship_guid) { + $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'"); + } + + if ($type != "") { + $where[] = "e.type='$type'"; + } + + if ($subtype) { + $where[] = "e.subtype=$subtype"; + } + + if ($owner_guid != "") { + $where[] = "e.container_guid='$owner_guid'"; + } + + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + // Select what we're joining based on the options + $joinon = "e.guid = r.guid_one"; + if (!$inverse_relationship) { + $joinon = "e.guid = r.guid_two"; + } + + if ($count) { + $query = "SELECT count(distinct e.guid) as total "; + } else { + $query = "SELECT distinct e.* "; + } + $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on $joinon where "; + foreach ($where as $w) { + $query .= " $w and "; + } + $query .= get_access_sql_suffix("e"); // Add access controls + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; + } + } + + return false; +} + +/** + * Returns a viewable list of entities by relationship + * + * @see elgg_view_entity_list + * + * @param string $relationship The relationship eg "friends_of" + * @param int $relationship_guid The guid of the entity to use query + * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" + * @param string $type The type of entity (eg 'object') + * @param string $subtype The entity subtype + * @param int $owner_guid The owner (default: all) + * @param int $limit The number of entities to display on a page + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow gallery view + * @param true|false $pagination Whether to display pagination (default: true) + * @return string The viewable list of entities + */ +function list_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship = false, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $pagination = true) { + $limit = (int) $limit; + $offset = (int) get_input('offset'); + $count = get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, "", $limit, $offset, true); + $entities = get_entities_from_relationship($relationship, $relationship_guid, $inverse_relationship, $type, $subtype, $owner_guid, "", $limit, $offset); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); +} + +/** + * Gets the number of entities by a the number of entities related to them in a particular way. + * This is a good way to get out the users with the most friends, or the groups with the most members. + * + * @param string $relationship The relationship eg "friends_of" + * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true) + * @param string $type The type of entity (default: all) + * @param string $subtype The entity subtype (default: all) + * @param int $owner_guid The owner of the entities (default: none) + * @param int $limit + * @param int $offset + * @param boolean $count Set to true if you want to count the number of entities instead (default false) + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @return array|int|false An array of entities, or the number of entities, or false on failure + */ + +function get_entities_by_relationship_count($relationship, $inverse_relationship = true, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_guid = 0) { + global $CONFIG; + + $relationship = sanitise_string($relationship); + $inverse_relationship = (bool)$inverse_relationship; + $type = sanitise_string($type); + if ($subtype AND !$subtype = get_subtype_id($type, $subtype)) { + return false; + } + $owner_guid = (int)$owner_guid; + $order_by = sanitise_string($order_by); + $limit = (int)$limit; + $offset = (int)$offset; + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + //$access = get_access_list(); + + $where = array(); + + if ($relationship!="") { + $where[] = "r.relationship='$relationship'"; + } + + if ($inverse_relationship) { + $on = 'e.guid = r.guid_two'; + } else { + $on = 'e.guid = r.guid_one'; + } + if ($type != "") { + $where[] = "e.type='$type'"; + } + + if ($subtype) { + $where[] = "e.subtype=$subtype"; + } + + if ($owner_guid != "") { + $where[] = "e.container_guid='$owner_guid'"; + } + + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + + if ($count) { + $query = "SELECT count(distinct e.guid) as total "; + } else { + $query = "SELECT e.*, count(e.guid) as total "; + } + + $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on {$on} where "; + + if (!empty($where)) { + foreach ($where as $w) { $query .= " $w and "; - $query .= get_access_sql_suffix("e"); // Add access controls - if (($meta_name!=="") || ($meta_value!=="")) $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls - - if (!$count) { - $query .= " group by e.guid "; - $query .= " order by total desc limit {$offset}, {$limit}"; // Add order and limit - - return get_data($query, "entity_row_to_elggstar"); - } else { - if ($count = get_data_row($query)) { - return $count->total; - } } - + } + $query .= get_access_sql_suffix("e"); // Add access controls + + if (!$count) { + $query .= " group by e.guid "; + $query .= " order by total desc limit {$offset}, {$limit}"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; + } + } + + return false; +} + +/** + * Displays a human-readable list of entities + * + * @param string $relationship The relationship eg "friends_of" + * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true) + * @param string $type The type of entity (eg 'object') + * @param string $subtype The entity subtype + * @param int $owner_guid The owner (default: all) + * @param int $limit The number of entities to display on a page + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow gallery view + * @param true|false $pagination Whether to display pagination (default: true) + * @return string The viewable list of entities + */ + +function list_entities_by_relationship_count($relationship, $inverse_relationship = true, $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = false, $pagination = true) { + $limit = (int) $limit; + $offset = (int) get_input('offset'); + $count = get_entities_by_relationship_count($relationship,$inverse_relationship,$type,$subtype,$owner_guid,0,0,true); + $entities = get_entities_by_relationship_count($relationship,$inverse_relationship,$type,$subtype,$owner_guid,$limit,$offset); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); +} + +/** + * Gets the number of entities by a the number of entities related to them in a particular way also constrained by + * metadata + * + * @param string $relationship The relationship eg "friends_of" + * @param int $relationship_guid The guid of the entity to use query + * @param bool $inverse_relationship Reverse the normal function of the query to instead say "give me all entities for whome $relationship_guid is a $relationship of" (default: true) + * @param String $meta_name The metadata name + * @param String $meta_value The metadata value + * @param string $type The type of entity (default: all) + * @param string $subtype The entity subtype (default: all) + * @param int $owner_guid The owner of the entities (default: none) + * @param int $limit + * @param int $offset + * @param boolean $count Set to true if you want to count the number of entities instead (default false) + * @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites. + * @return array|int|false An array of entities, or the number of entities, or false on failure + */ +function get_entities_from_relationships_and_meta($relationship, $relationship_guid, $inverse_relationship = false, $meta_name = "", $meta_value = "", $type = "", $subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $count = false, $site_guid = 0) { + global $CONFIG; + + $relationship = sanitise_string($relationship); + $inverse_relationship = (bool)$inverse_relationship; + $relationship_guid = (int)$relationship_guid; + $type = sanitise_string($type); + if ($subtype AND !$subtype = get_subtype_id($type, $subtype)) { return false; } - - /** - * Sets the URL handler for a particular relationship type - * - * @param string $function_name The function to register - * @param string $relationship_type The relationship type. - * @return true|false Depending on success - */ - function register_relationship_url_handler($function_name, $relationship_type = "all") { - global $CONFIG; - - if (!is_callable($function_name)) return false; - - if (!isset($CONFIG->relationship_url_handler)) { - $CONFIG->relationship_url_handler = array(); + + $owner_guid = (int)$owner_guid; + $order_by = sanitise_string($order_by); + $limit = (int)$limit; + $offset = (int)$offset; + $site_guid = (int) $site_guid; + if ($site_guid == 0) { + $site_guid = $CONFIG->site_guid; + } + + $meta_n = get_metastring_id($meta_name); + $meta_v = get_metastring_id($meta_value); + + //$access = get_access_list(); + + $where = array(); + + if ($relationship!="") { + $where[] = "r.relationship='$relationship'"; + } + + $on = "e.guid = r.guid_one"; + if (!$inverse_relationship) { + $on = "e.guid = r.guid_two"; + } + + if ($type != "") { + $where[] = "e.type='$type'"; + } + if ($subtype) { + $where[] = "e.subtype=$subtype"; + } + if ($owner_guid != "") { + $where[] = "e.container_guid='$owner_guid'"; + } + if ($site_guid > 0) { + $where[] = "e.site_guid = {$site_guid}"; + } + if ($relationship_guid) { + $where[] = ($inverse_relationship ? "r.guid_two='$relationship_guid'" : "r.guid_one='$relationship_guid'"); + } + + + $metajoin = ""; + if (($meta_name!=="") || ($meta_value!=="")) { + $metajoin = " JOIN {$CONFIG->dbprefix}metadata m on e.guid=m.entity_guid"; + + if ($meta_name!=="") { + $where[] = "m.name_id='$meta_n'"; + } + if ($meta_value!=="") { + $where[] = "m.value_id='$meta_v'"; } - - $CONFIG->relationship_url_handler[$relationship_type] = $function_name; - - return true; - } - - /** - * Get the url for a given relationship. - * - * @param unknown_type $id - * @return unknown - */ - function get_relationship_url($id) - { - global $CONFIG; - - $id = (int)$id; - - if ($relationship = get_relationship($id)) - { - $view = elgg_get_viewtype(); - - $guid = $relationship->guid_one; - $type = $relationship->relationship; - - $url = ""; - - $function = ""; - if (isset($CONFIG->relationship_url_handler[$type])) - $function = $CONFIG->relationship_url_handler[$type]; - if (isset($CONFIG->relationship_url_handler['all'])) - $function = $CONFIG->relationship_url_handler['all']; - - if (is_callable($function)) { - $url = $function($relationship); - } - - if ($url == "") { - - $nameid = $relationship->id; - - $url = $CONFIG->wwwroot . "export/$view/$guid/relationship/$nameid/"; - } - - return $url; - + + if ($count) { + $query = "SELECT count(distinct e.guid) as total "; + } else { + $query = "SELECT distinct e.*, count(e.guid) as total "; + } + + $query .= " from {$CONFIG->dbprefix}entity_relationships r JOIN {$CONFIG->dbprefix}entities e on {$on} {$metajoin} where "; + + if (!empty($where)) { + foreach ($where as $w) { + $query .= " $w and "; } - + } + $query .= get_access_sql_suffix("e"); // Add access controls + if (($meta_name!=="") || ($meta_value!=="")) { + $query .= ' and ' . get_access_sql_suffix("m"); // Add access controls + } + + if (!$count) { + $query .= " group by e.guid "; + $query .= " order by total desc limit {$offset}, {$limit}"; // Add order and limit + + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; + } + } + + return false; +} + +/** + * Sets the URL handler for a particular relationship type + * + * @param string $function_name The function to register + * @param string $relationship_type The relationship type. + * @return true|false Depending on success + */ +function register_relationship_url_handler($function_name, $relationship_type = "all") { + global $CONFIG; + + if (!is_callable($function_name)) { return false; } - - /**** HELPER FUNCTIONS FOR RELATIONSHIPS OF TYPE 'ATTACHED' ****/ - - /** - * Function to determine if the object trying to attach to other, has already done so - * @param int $guid_one This is the target object - * @param int $guid_two This is the object trying to attach to $guid_one - * @return true | false - **/ - - function already_attached($guid_one, $guid_two){ - - if($attached = check_entity_relationship($guid_one, "attached", $guid_two)){ - return true; - }else{ - return false; - } - } - - /** - * Function to get all objects attached to a particular object - * @param int $guid - * @param string $type - the type of object to return e.g. 'file', 'friend_of' etc - * @return an array of objects - **/ - - function get_attachments($guid, $type=""){ - - $attached = get_entities_from_relationship("attached", $guid, $inverse_relationship = false, $type, $subtype = "", $owner_guid = 0, $order_by = "time_created desc", $limit = 10, $offset = 0, $count = false, $site_guid = 0); - return $attached; - - } - - /** - * Function to remove a particular attachment between two objects - * @param int $guid_one This is the target object - * @param int $guid_two This is the object to remove from $guid_one - * @return a view - **/ - - function remove_attachment($guid_one, $guid_two){ - - if(already_attached($guid_one, $guid_two)) - remove_entity_relationship($guid_one, "attached", $guid_two); - - } - - - - /** - * Function to start the process of attaching one object to another - * @param int $guid_one This is the target object - * @param int $guid_two This is the object trying to attach to $guid_one - * @return a view - **/ - - function make_attachment($guid_one, $guid_two){ - - if(!(already_attached($guid_one, $guid_two))) - if(add_entity_relationship($guid_one, "attached", $guid_two)) - return true; - - } - - /** - * Handler called by trigger_plugin_hook on the "import" event. - */ - function import_relationship_plugin_hook($hook, $entity_type, $returnvalue, $params) - { - $element = $params['element']; - - $tmp = NULL; - - if ($element instanceof ODDRelationship) - { - $tmp = new ElggRelationship(); - $tmp->import($element); - - return $tmp; + + if (!isset($CONFIG->relationship_url_handler)) { + $CONFIG->relationship_url_handler = array(); + } + + $CONFIG->relationship_url_handler[$relationship_type] = $function_name; + + return true; +} + +/** + * Get the url for a given relationship. + * + * @param unknown_type $id + * @return unknown + */ +function get_relationship_url($id) { + global $CONFIG; + + $id = (int)$id; + + if ($relationship = get_relationship($id)) { + $view = elgg_get_viewtype(); + + $guid = $relationship->guid_one; + $type = $relationship->relationship; + + $url = ""; + + $function = ""; + if (isset($CONFIG->relationship_url_handler[$type])) { + $function = $CONFIG->relationship_url_handler[$type]; + } + if (isset($CONFIG->relationship_url_handler['all'])) { + $function = $CONFIG->relationship_url_handler['all']; + } + + if (is_callable($function)) { + $url = $function($relationship); } + + if ($url == "") { + $nameid = $relationship->id; + + $url = $CONFIG->wwwroot . "export/$view/$guid/relationship/$nameid/"; + } + + return $url; } - - /** - * Handler called by trigger_plugin_hook on the "export" event. - */ - function export_relationship_plugin_hook($hook, $entity_type, $returnvalue, $params) - { - global $CONFIG; - - // Sanity check values - if ((!is_array($params)) && (!isset($params['guid']))) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:GUIDNotForExport')); - - if (!is_array($returnvalue)) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue')); - - $guid = (int)$params['guid']; - - $result = get_entity_relationships($guid); - - if ($result) - { - foreach ($result as $r) - $returnvalue[] = $r->export(); + + return false; +} + +/**** HELPER FUNCTIONS FOR RELATIONSHIPS OF TYPE 'ATTACHED' ****/ + +/** + * Function to determine if the object trying to attach to other, has already done so + * @param int $guid_one This is the target object + * @param int $guid_two This is the object trying to attach to $guid_one + * @return true | false + **/ + +function already_attached($guid_one, $guid_two){ + if ($attached = check_entity_relationship($guid_one, "attached", $guid_two)){ + return true; + } else { + return false; + } +} + +/** + * Function to get all objects attached to a particular object + * @param int $guid + * @param string $type - the type of object to return e.g. 'file', 'friend_of' etc + * @return an array of objects +**/ + +function get_attachments($guid, $type=""){ + $attached = get_entities_from_relationship("attached", $guid, $inverse_relationship = false, $type, $subtype = "", $owner_guid = 0, $order_by = "time_created desc", $limit = 10, $offset = 0, $count = false, $site_guid = 0); + return $attached; +} + +/** + * Function to remove a particular attachment between two objects + * @param int $guid_one This is the target object + * @param int $guid_two This is the object to remove from $guid_one + * @return a view +**/ + +function remove_attachment($guid_one, $guid_two){ + if(already_attached($guid_one, $guid_two)) { + remove_entity_relationship($guid_one, "attached", $guid_two); + } +} + +/** + * Function to start the process of attaching one object to another + * @param int $guid_one This is the target object + * @param int $guid_two This is the object trying to attach to $guid_one + * @return a view +**/ + +function make_attachment($guid_one, $guid_two){ + if (!(already_attached($guid_one, $guid_two))) { + if (add_entity_relationship($guid_one, "attached", $guid_two)) { + return true; } - - return $returnvalue; - } - - /** - * An event listener which will notify users based on certain events. - * - * @param unknown_type $event - * @param unknown_type $object_type - * @param unknown_type $object - */ - function relationship_notification_hook($event, $object_type, $object) - { - global $CONFIG; - - if ( - ($object instanceof ElggRelationship) && - ($event == 'create') && - ($object_type == 'friend') - ) - { - $user_one = get_entity($object->guid_one); - $user_two = get_entity($object->guid_two); - - // Notify target user - return notify_user($object->guid_two, $object->guid_one, sprintf(elgg_echo('friend:newfriend:subject'), $user_one->name), - sprintf(elgg_echo("friend:newfriend:body"), $user_one->name, $CONFIG->site->url . "pg/profile/" . $user_one->username) - ); + } +} + +/** + * Handler called by trigger_plugin_hook on the "import" event. + */ +function import_relationship_plugin_hook($hook, $entity_type, $returnvalue, $params) { + $element = $params['element']; + + $tmp = NULL; + + if ($element instanceof ODDRelationship) { + $tmp = new ElggRelationship(); + $tmp->import($element); + + return $tmp; + } +} + +/** + * Handler called by trigger_plugin_hook on the "export" event. + */ +function export_relationship_plugin_hook($hook, $entity_type, $returnvalue, $params) { + global $CONFIG; + + // Sanity check values + if ((!is_array($params)) && (!isset($params['guid']))) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:GUIDNotForExport')); + } + + if (!is_array($returnvalue)) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue')); + } + + $guid = (int)$params['guid']; + + $result = get_entity_relationships($guid); + + if ($result) { + foreach ($result as $r) { + $returnvalue[] = $r->export(); } } - - /** Register the import hook */ - register_plugin_hook("import", "all", "import_relationship_plugin_hook", 3); - - /** Register the hook, ensuring entities are serialised first */ - register_plugin_hook("export", "all", "export_relationship_plugin_hook", 3); - - /** Register event to listen to some events **/ - register_elgg_event_handler('create','friend','relationship_notification_hook'); -?> \ No newline at end of file + + return $returnvalue; +} + +/** + * An event listener which will notify users based on certain events. + * + * @param unknown_type $event + * @param unknown_type $object_type + * @param unknown_type $object + */ +function relationship_notification_hook($event, $object_type, $object) { + global $CONFIG; + + if ( + ($object instanceof ElggRelationship) && + ($event == 'create') && + ($object_type == 'friend') + ) + { + $user_one = get_entity($object->guid_one); + $user_two = get_entity($object->guid_two); + + // Notify target user + return notify_user($object->guid_two, $object->guid_one, sprintf(elgg_echo('friend:newfriend:subject'), $user_one->name), + sprintf(elgg_echo("friend:newfriend:body"), $user_one->name, $CONFIG->site->url . "pg/profile/" . $user_one->username) + ); + } +} + +/** Register the import hook */ +register_plugin_hook("import", "all", "import_relationship_plugin_hook", 3); + +/** Register the hook, ensuring entities are serialised first */ +register_plugin_hook("export", "all", "export_relationship_plugin_hook", 3); + +/** Register event to listen to some events **/ +register_elgg_event_handler('create','friend','relationship_notification_hook'); \ No newline at end of file diff --git a/engine/lib/river2.php b/engine/lib/river2.php index 510ec7b8c..799af013c 100644 --- a/engine/lib/river2.php +++ b/engine/lib/river2.php @@ -1,295 +1,285 @@ access_id; + } + $annotation_id = (int)$annotation_id; + $type = $object->getType(); + $subtype = $object->getSubtype(); + $action_type = sanitise_string($action_type); - * @author Curverider Ltd + // Load config + global $CONFIG; - * @link http://elgg.org/ - */ + // Attempt to save river item; return success status + return insert_data("insert into {$CONFIG->dbprefix}river " . + " set type = '{$type}', " . + " subtype = '{$subtype}', " . + " action_type = '{$action_type}', " . + " access_id = {$access_id}, " . + " view = '{$view}', " . + " subject_guid = {$subject_guid}, " . + " object_guid = {$object_guid}, " . + " posted = {$posted}, " . + " annotation_id = {$annotation_id} "); +} - /** - * Adds an item to the river. - * - * @param string $view The view that will handle the river item (must exist) - * @param string $action_type An arbitrary one-word string to define the action (eg 'comment', 'create') - * @param int $subject_guid The GUID of the entity doing the action - * @param int $object_guid The GUID of the entity being acted upon - * @param int $access_id The access ID of the river item (default: same as the object) - * @param int $posted The UNIX epoch timestamp of the river item (default: now) - * @return true|false Depending on success - */ - function add_to_river($view,$action_type,$subject_guid,$object_guid,$access_id = "",$posted = 0, $annotation_id = 0) - { - - // Sanitise variables - if (!elgg_view_exists($view)) return false; - if (!($subject = get_entity($subject_guid))) return false; - if (!($object = get_entity($object_guid))) return false; - if (empty($action_type)) return false; - if ($posted == 0) $posted = time(); - if ($access_id === "") $access_id = $object->access_id; - $annotation_id = (int)$annotation_id; - $type = $object->getType(); - $subtype = $object->getSubtype(); - $action_type = sanitise_string($action_type); - - // Load config - global $CONFIG; - - // Attempt to save river item; return success status - return insert_data("insert into {$CONFIG->dbprefix}river " . - " set type = '{$type}', " . - " subtype = '{$subtype}', " . - " action_type = '{$action_type}', " . - " access_id = {$access_id}, " . - " view = '{$view}', " . - " subject_guid = {$subject_guid}, " . - " object_guid = {$object_guid}, " . - " posted = {$posted}, " . - " annotation_id = {$annotation_id} "); - - } - - /** - * Removes all items relating to a particular acting entity from the river - * - * @param int $subject_guid The GUID of the entity - * @return true|false Depending on success - */ - function remove_from_river_by_subject( - $subject_guid - ) { - - // Sanitise - $subject_guid = (int) $subject_guid; - - // Load config - global $CONFIG; - - // Remove - return delete_data("delete from {$CONFIG->dbprefix}river where subject_guid = {$subject_guid}"); - +/** + * Removes all items relating to a particular acting entity from the river + * + * @param int $subject_guid The GUID of the entity + * @return true|false Depending on success + */ +function remove_from_river_by_subject($subject_guid) { + // Sanitise + $subject_guid = (int) $subject_guid; + + // Load config + global $CONFIG; + + // Remove + return delete_data("delete from {$CONFIG->dbprefix}river where subject_guid = {$subject_guid}"); +} + +/** + * Removes all items relating to a particular entity being acted upon from the river + * + * @param int $object_guid The GUID of the entity + * @return true|false Depending on success + */ +function remove_from_river_by_object($object_guid) { + // Sanitise + $object_guid = (int) $object_guid; + + // Load config + global $CONFIG; + + // Remove + return delete_data("delete from {$CONFIG->dbprefix}river where object_guid = {$object_guid}"); +} + +/** + * Sets the access ID on river items for a particular object + * + * @param int $object_guid The GUID of the entity + * @param int $access_id The access ID + * @return true|false Depending on success + */ +function update_river_access_by_object($object_guid, $access_id) { + // Sanitise + $object_guid = (int) $object_guid; + $access_id = (int) $access_id; + + // Load config + global $CONFIG; + + // Remove + return update_data("update {$CONFIG->dbprefix}river set access_id = {$access_id} where object_guid = {$object_guid}"); +} + +/** + * Retrieves items from the river. All parameters are optional. + * + * @param int|array $subject_guid Acting entity to restrict to. Default: all + * @param int|array $object_guid Entity being acted on to restrict to. Default: all + * @param string $subject_relationship If set to a relationship type, this will use $subject_guid as the starting point and set the subjects to be all users this entity has this relationship with (eg 'friend'). Default: blank + * @param string $type The type of entity to restrict to. Default: all + * @param string $subtype The subtype of entity to restrict to. Default: all + * @param string $action_type The type of river action to restrict to. Default: all + * @param int $limit The number of items to retrieve. Default: 20 + * @param int $offset The page offset. Default: 0 + * @param int $posted_min The minimum time period to look at. Default: none + * @param int $posted_max The maximum time period to look at. Default: none + * @return array|false Depending on success + */ +function get_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '', $type = '', + $subtype = '', $action_type = '', $limit = 20, $offset = 0, $posted_min = 0, $posted_max = 0) { + + // Get config + global $CONFIG; + + // Sanitise variables + if (!is_array($subject_guid)) { + $subject_guid = (int) $subject_guid; + } else { + foreach($subject_guid as $key => $temp) { + $subject_guid[$key] = (int) $temp; } - - /** - * Removes all items relating to a particular entity being acted upon from the river - * - * @param int $object_guid The GUID of the entity - * @return true|false Depending on success - */ - function remove_from_river_by_object( - $object_guid - ) { - - // Sanitise - $object_guid = (int) $object_guid; - - // Load config - global $CONFIG; - - // Remove - return delete_data("delete from {$CONFIG->dbprefix}river where object_guid = {$object_guid}"); - + } + if (!is_array($object_guid)) { + $object_guid = (int) $object_guid; + } else { + foreach($object_guid as $key => $temp) { + $object_guid[$key] = (int) $temp; } + } + if (!empty($type)) { + $type = sanitise_string($type); + } + if (!empty($subtype)) { + $subtype = sanitise_string($subtype); + } + if (!empty($action_type)) { + $action_type = sanitise_string($action_type); + } + $limit = (int) $limit; + $offset = (int) $offset; + $posted_min = (int) $posted_min; + $posted_max = (int) $posted_max; + + // Construct 'where' clauses for the river + $where = array(); + $where[] = str_replace("and enabled='yes'",'',str_replace('owner_guid','subject_guid',get_access_sql_suffix())); - /** - * Sets the access ID on river items for a particular object - * - * @param int $object_guid The GUID of the entity - * @param int $access_id The access ID - * @return true|false Depending on success - */ - function update_river_access_by_object( - $object_guid, $access_id - ) { - - // Sanitise - $object_guid = (int) $object_guid; - $access_id = (int) $access_id; - - // Load config - global $CONFIG; - - // Remove - return update_data("update {$CONFIG->dbprefix}river set access_id = {$access_id} where object_guid = {$object_guid}"); - + if (empty($subject_relationship)) { + if (!empty($subject_guid)) { + if (!is_array($subject_guid)) { + $where[] = " subject_guid = {$subject_guid} "; + } else { + $where[] = " subject_guid in (" . implode(',',$subject_guid) . ") "; + } } - - /** - * Retrieves items from the river. All parameters are optional. - * - * @param int|array $subject_guid Acting entity to restrict to. Default: all - * @param int|array $object_guid Entity being acted on to restrict to. Default: all - * @param string $subject_relationship If set to a relationship type, this will use $subject_guid as the starting point and set the subjects to be all users this entity has this relationship with (eg 'friend'). Default: blank - * @param string $type The type of entity to restrict to. Default: all - * @param string $subtype The subtype of entity to restrict to. Default: all - * @param string $action_type The type of river action to restrict to. Default: all - * @param int $limit The number of items to retrieve. Default: 20 - * @param int $offset The page offset. Default: 0 - * @param int $posted_min The minimum time period to look at. Default: none - * @param int $posted_max The maximum time period to look at. Default: none - * @return array|false Depending on success - */ - function get_river_items( - $subject_guid = 0, - $object_guid = 0, - $subject_relationship = '', - $type = '', - $subtype = '', - $action_type = '', - $limit = 20, - $offset = 0, - $posted_min = 0, - $posted_max = 0 - ) { - - // Get config - global $CONFIG; - - // Sanitise variables - if (!is_array($subject_guid)) { - $subject_guid = (int) $subject_guid; - } else { - foreach($subject_guid as $key => $temp) { - $subject_guid[$key] = (int) $temp; - } + } else { + if (!is_array($subject_guid)) { + if ($entities = get_entities_from_relationship($subject_relationship,$subject_guid,false,'','',0,'',9999)) { + $guids = array(); + foreach($entities as $entity) { + $guids[] = (int) $entity->guid; } - if (!is_array($object_guid)) { - $object_guid = (int) $object_guid; - } else { - foreach($object_guid as $key => $temp) { - $object_guid[$key] = (int) $temp; - } - } - if (!empty($type)) $type = sanitise_string($type); - if (!empty($subtype)) $subtype = sanitise_string($subtype); - if (!empty($action_type)) $action_type = sanitise_string($action_type); - $limit = (int) $limit; - $offset = (int) $offset; - $posted_min = (int) $posted_min; - $posted_max = (int) $posted_max; - - // Construct 'where' clauses for the river - $where = array(); - $where[] = str_replace("and enabled='yes'",'',str_replace('owner_guid','subject_guid',get_access_sql_suffix())); - - if (empty($subject_relationship)) { - if (!empty($subject_guid)) - if (!is_array($subject_guid)) { - $where[] = " subject_guid = {$subject_guid} "; - } else { - $where[] = " subject_guid in (" . implode(',',$subject_guid) . ") "; - } - } else { - if (!is_array($subject_guid)) - if ($entities = get_entities_from_relationship($subject_relationship,$subject_guid,false,'','',0,'',9999)) { - $guids = array(); - foreach($entities as $entity) $guids[] = (int) $entity->guid; - // $guids[] = $subject_guid; - $where[] = " subject_guid in (" . implode(',',$guids) . ") "; - } else { - return array(); - } - } - if (!empty($object_guid)) - if (!is_array($object_guid)) { - $where[] = " object_guid = {$object_guid} "; - } else { - $where[] = " object_guid in (" . implode(',',$object_guid) . ") "; - } - if (!empty($type)) $where[] = " type = '{$type}' "; - if (!empty($subtype)) $where[] = " subtype = '{$subtype}' "; - if (!empty($action_type)) $where[] = " action_type = '{$action_type}' "; - if (!empty($posted_min)) $where[] = " posted > {$posted_min} "; - if (!empty($posted_max)) $where[] = " posted < {$posted_max} "; - - $whereclause = implode(' and ', $where); - - // Construct main SQL - $sql = "select id,type,subtype,action_type,access_id,view,subject_guid,object_guid,posted,annotation_id from {$CONFIG->dbprefix}river where {$whereclause} order by posted desc limit {$offset},{$limit}"; - - // Get data - return get_data($sql); - + // $guids[] = $subject_guid; + $where[] = " subject_guid in (" . implode(',',$guids) . ") "; + } else { + return array(); + } + } + } + if (!empty($object_guid)) + if (!is_array($object_guid)) { + $where[] = " object_guid = {$object_guid} "; + } else { + $where[] = " object_guid in (" . implode(',',$object_guid) . ") "; } - - /** - * Returns a human-readable representation of a river item - * - * @see get_river_items - * - * @param stdClass $item A river item object as returned from get_river_items - * @return string|false Depending on success - */ - function elgg_view_river_item($item) { - if (isset($item->view)) { + if (!empty($type)) { + $where[] = " type = '{$type}' "; + } + if (!empty($subtype)) { + $where[] = " subtype = '{$subtype}' "; + } + if (!empty($action_type)) { + $where[] = " action_type = '{$action_type}' "; + } + if (!empty($posted_min)) { + $where[] = " posted > {$posted_min} "; + } + if (!empty($posted_max)) { + $where[] = " posted < {$posted_max} "; + } - $object = get_entity($item->object_guid); - if (!$object) { - $body = elgg_view('river/item/noaccess'); - } else { - if (elgg_view_exists($item->view)) { - $body = elgg_view($item->view,array( - 'item' => $item - )); - } - } - return elgg_view('river/item/wrapper',array( - 'item' => $item, - 'body' => $body - )); - + $whereclause = implode(' and ', $where); + + // Construct main SQL + $sql = "select id,type,subtype,action_type,access_id,view,subject_guid,object_guid,posted,annotation_id from {$CONFIG->dbprefix}river where {$whereclause} order by posted desc limit {$offset},{$limit}"; + + // Get data + return get_data($sql); +} + +/** + * Returns a human-readable representation of a river item + * + * @see get_river_items + * + * @param stdClass $item A river item object as returned from get_river_items + * @return string|false Depending on success + */ +function elgg_view_river_item($item) { + if (isset($item->view)) { + $object = get_entity($item->object_guid); + if (!$object) { + $body = elgg_view('river/item/noaccess'); + } else { + if (elgg_view_exists($item->view)) { + $body = elgg_view($item->view,array( + 'item' => $item + )); } - return false; } - - /** - * Returns a human-readable version of the river. - * - * @param int|array $subject_guid Acting entity to restrict to. Default: all - * @param int|array $object_guid Entity being acted on to restrict to. Default: all - * @param string $subject_relationship If set to a relationship type, this will use $subject_guid as the starting point and set the subjects to be all users this entity has this relationship with (eg 'friend'). Default: blank - * @param string $type The type of entity to restrict to. Default: all - * @param string $subtype The subtype of entity to restrict to. Default: all - * @param string $action_type The type of river action to restrict to. Default: all - * @param int $limit The number of items to retrieve. Default: 20 - * @param int $posted_min The minimum time period to look at. Default: none - * @param int $posted_max The maximum time period to look at. Default: none - * @return string Human-readable river. - */ - function elgg_view_river_items($subject_guid = 0, - $object_guid = 0, - $subject_relationship = '', - $type = '', - $subtype = '', - $action_type = '', - $limit = 20, - $posted_min = 0, - $posted_max = 0, - $pagination = true) { - - // Get input from outside world and sanitise it - $offset = (int) get_input('offset',0); - - // Get river items, if they exist - if ($riveritems = get_river_items($subject_guid,$object_guid,$subject_relationship,$type,$subtype,$action_type,($limit + 1),$offset,$posted_min,$posted_max)) { + return elgg_view('river/item/wrapper',array( + 'item' => $item, + 'body' => $body + )); + } + return false; +} - return elgg_view('river/item/list',array( - 'limit' => $limit, - 'offset' => $offset, - 'items' => $riveritems, - 'pagination' => $pagination - )); - - } - - return ''; - - } +/** + * Returns a human-readable version of the river. + * + * @param int|array $subject_guid Acting entity to restrict to. Default: all + * @param int|array $object_guid Entity being acted on to restrict to. Default: all + * @param string $subject_relationship If set to a relationship type, this will use $subject_guid as the starting point and set the subjects to be all users this entity has this relationship with (eg 'friend'). Default: blank + * @param string $type The type of entity to restrict to. Default: all + * @param string $subtype The subtype of entity to restrict to. Default: all + * @param string $action_type The type of river action to restrict to. Default: all + * @param int $limit The number of items to retrieve. Default: 20 + * @param int $posted_min The minimum time period to look at. Default: none + * @param int $posted_max The maximum time period to look at. Default: none + * @return string Human-readable river. + */ +function elgg_view_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '', + $type = '', $subtype = '', $action_type = '', $limit = 20, $posted_min = 0, $posted_max = 0, $pagination = true) { + + // Get input from outside world and sanitise it + $offset = (int) get_input('offset',0); + + // Get river items, if they exist + if ($riveritems = get_river_items($subject_guid,$object_guid,$subject_relationship,$type,$subtype,$action_type,($limit + 1),$offset,$posted_min,$posted_max)) { + + return elgg_view('river/item/list',array( + 'limit' => $limit, + 'offset' => $offset, + 'items' => $riveritems, + 'pagination' => $pagination + )); + + } -?> \ No newline at end of file + return ''; +} \ No newline at end of file diff --git a/engine/lib/search.php b/engine/lib/search.php index 222c0b6e9..0f6c0a12d 100644 --- a/engine/lib/search.php +++ b/engine/lib/search.php @@ -1,50 +1,52 @@ - * @link http://elgg.org/ - */ +/** + * Elgg search helper functions. + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + */ - /** - * Initialise search helper functions. - * - */ - function search_init() - { - register_page_handler('search','search_page_handler'); +/** + * Initialise search helper functions. + * + */ +function search_init() { + register_page_handler('search','search_page_handler'); +} + +/** + * Page handler for search + * + * @param array $page Page elements from pain page handler + */ +function search_page_handler($page) { + global $CONFIG; + + if(!get_input('tag')) { + set_input('tag', $page[0]); } - - /** - * Page handler for search - * - * @param array $page Page elements from pain page handler - */ - function search_page_handler($page) - { - global $CONFIG; - - if(!get_input('tag')) { - set_input('tag', $page[0]); - } - if (isset($page[0])) { - switch ($page[0]) { - case 'user' : - case 'users' : include_once($CONFIG->path . "search/users.php"); break; - - case 'group' : - case 'groups' : include_once($CONFIG->path . "search/groups.php"); break; - - default: include_once($CONFIG->path . "search/index.php"); - } + if (isset($page[0])) { + switch ($page[0]) { + case 'user' : + case 'users' : + include_once($CONFIG->path . "search/users.php"); + break; + + case 'group' : + case 'groups' : + include_once($CONFIG->path . "search/groups.php"); + break; + + default: + include_once($CONFIG->path . "search/index.php"); } - else - include_once($CONFIG->path . "search/index.php"); + } else { + include_once($CONFIG->path . "search/index.php"); } +} - /** Register init system event **/ - register_elgg_event_handler('init','system','search_init'); -?> +/** Register init system event **/ +register_elgg_event_handler('init','system','search_init'); \ No newline at end of file diff --git a/engine/lib/sites.php b/engine/lib/sites.php index e12a745c5..7a1375d46 100644 --- a/engine/lib/sites.php +++ b/engine/lib/sites.php @@ -1,614 +1,611 @@ + * @link http://elgg.org/ + */ +/** + * ElggSite + * Representation of a "site" in the system. + * @author Curverider Ltd + * @package Elgg + * @subpackage Core + */ +class ElggSite extends ElggEntity { /** - * Elgg sites - * Functions to manage multiple or single sites in an Elgg install - * - * @package Elgg - * @subpackage Core - - * @author Curverider Ltd - - * @link http://elgg.org/ + * Initialise the attributes array. + * This is vital to distinguish between metadata and base parameters. + * + * Place your base parameters here. */ + protected function initialise_attributes() { + parent::initialise_attributes(); + + $this->attributes['type'] = "site"; + $this->attributes['name'] = ""; + $this->attributes['description'] = ""; + $this->attributes['url'] = ""; + $this->attributes['tables_split'] = 2; + } /** - * ElggSite - * Representation of a "site" in the system. - * @author Curverider Ltd - * @package Elgg - * @subpackage Core + * Construct a new site object, optionally from a given id value. + * + * @param mixed $guid If an int, load that GUID. + * If a db row then will attempt to load the rest of the data. + * @throws Exception if there was a problem creating the site. */ - class ElggSite extends ElggEntity - { - /** - * Initialise the attributes array. - * This is vital to distinguish between metadata and base parameters. - * - * Place your base parameters here. - */ - protected function initialise_attributes() - { - parent::initialise_attributes(); - - $this->attributes['type'] = "site"; - $this->attributes['name'] = ""; - $this->attributes['description'] = ""; - $this->attributes['url'] = ""; - $this->attributes['tables_split'] = 2; - } - - /** - * Construct a new site object, optionally from a given id value. - * - * @param mixed $guid If an int, load that GUID. - * If a db row then will attempt to load the rest of the data. - * @throws Exception if there was a problem creating the site. - */ - function __construct($guid = null) - { - $this->initialise_attributes(); - - if (!empty($guid)) - { - // Is $guid is a DB row - either a entity row, or a site table row. - if ($guid instanceof stdClass) { - // Load the rest - if (!$this->load($guid->guid)) - throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid)); + function __construct($guid = null) { + $this->initialise_attributes(); + + if (!empty($guid)) { + // Is $guid is a DB row - either a entity row, or a site table row. + if ($guid instanceof stdClass) { + // Load the rest + if (!$this->load($guid->guid)) { + throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid)); } - - // Is $guid is an ElggSite? Use a copy constructor - else if ($guid instanceof ElggSite) - { - foreach ($guid->attributes as $key => $value) - $this->attributes[$key] = $value; + } + + // Is $guid is an ElggSite? Use a copy constructor + else if ($guid instanceof ElggSite) { + foreach ($guid->attributes as $key => $value) { + $this->attributes[$key] = $value; } - - // Is this is an ElggEntity but not an ElggSite = ERROR! - else if ($guid instanceof ElggEntity) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggSite')); - - // See if this is a URL - else if (strpos($guid, "http")!==false) - { - $guid = get_site_by_url($guid); - foreach ($guid->attributes as $key => $value) - $this->attributes[$key] = $value; - + } + + // Is this is an ElggEntity but not an ElggSite = ERROR! + else if ($guid instanceof ElggEntity) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggSite')); + } + + // See if this is a URL + else if (strpos($guid, "http") !== false) { + $guid = get_site_by_url($guid); + foreach ($guid->attributes as $key => $value) { + $this->attributes[$key] = $value; } - - // We assume if we have got this far, $guid is an int - else if (is_numeric($guid)) { - if (!$this->load($guid)) throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid)); + } + + // We assume if we have got this far, $guid is an int + else if (is_numeric($guid)) { + if (!$this->load($guid)) { + throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid)); } - - else - throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue')); + } + + else { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue')); } } - - /** - * Override the load function. - * This function will ensure that all data is loaded (were possible), so - * if only part of the ElggSite is loaded, it'll load the rest. - * - * @param int $guid - */ - protected function load($guid) - { - // Test to see if we have the generic stuff - if (!parent::load($guid)) - return false; - - // Check the type - if ($this->attributes['type']!='site') - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class())); - - // Load missing data - $row = get_site_entity_as_row($guid); - if (($row) && (!$this->isFullyLoaded())) $this->attributes['tables_loaded'] ++; // If $row isn't a cached copy then increment the counter - - // Now put these into the attributes array as core values - $objarray = (array) $row; - foreach($objarray as $key => $value) - $this->attributes[$key] = $value; - - return true; - } - - /** - * Override the save function. - */ - public function save() - { - // Save generic stuff - if (!parent::save()) - return false; - - // Now save specific stuff - return create_site_entity($this->get('guid'), $this->get('name'), $this->get('description'), $this->get('url')); + } + + /** + * Override the load function. + * This function will ensure that all data is loaded (were possible), so + * if only part of the ElggSite is loaded, it'll load the rest. + * + * @param int $guid + */ + protected function load($guid) { + // Test to see if we have the generic stuff + if (!parent::load($guid)) { + return false; } - - /** - * Delete this site. - */ - public function delete() - { - global $CONFIG; - if ($CONFIG->site->getGUID() == $this->guid) - throw new SecurityException('SecurityException:deletedisablecurrentsite'); - - return parent::delete(); + + // Check the type + if ($this->attributes['type']!='site') { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class())); } - - /** - * Disable override to add safety rail. - * - * @param unknown_type $reason - */ - public function disable($reason = "") - { - global $CONFIG; - if ($CONFIG->site->getGUID() == $this->guid) - throw new SecurityException('SecurityException:deletedisablecurrentsite'); - - return parent::disable($reason); + + // Load missing data + $row = get_site_entity_as_row($guid); + if (($row) && (!$this->isFullyLoaded())) { + // If $row isn't a cached copy then increment the counter + $this->attributes['tables_loaded'] ++; } - - /** - * Return a list of users using this site. - * - * @param int $limit - * @param int $offset - * @return array of ElggUsers - */ - public function getMembers($limit = 10, $offset = 0) { get_site_members($this->getGUID(), $limit, $offset); } - - /** - * Add a user to the site. - * - * @param int $user_guid - */ - public function addUser($user_guid) { return add_site_user($this->getGUID(), $user_guid); } - - /** - * Remove a site user. - * - * @param int $user_guid - */ - public function removeUser($user_guid) { return remove_site_user($this->getGUID(), $user_guid); } - - /** - * Get an array of member ElggObjects. - * - * @param string $subtype - * @param int $limit - * @param int $offset - */ - public function getObjects($subtype="", $limit = 10, $offset = 0) { get_site_objects($this->getGUID(), $subtype, $limit, $offset); } - - /** - * Add an object to the site. - * - * @param int $user_id - */ - public function addObject($object_guid) { return add_site_object($this->getGUID(), $object_guid); } - - /** - * Remove a site user. - * - * @param int $user_id - */ - public function removeObject($object_guid) { return remove_site_object($this->getGUID(), $object_guid); } - - /** - * Get the collections associated with a site. - * - * @param string $type - * @param int $limit - * @param int $offset - * @return unknown - */ - public function getCollections($subtype="", $limit = 10, $offset = 0) { get_site_collections($this->getGUID(), $subtype, $limit, $offset); } - - // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// - - /** - * Return an array of fields which can be exported. - */ - public function getExportableValues() - { - return array_merge(parent::getExportableValues(), array( - 'name', - 'description', - 'url', - )); + + // Now put these into the attributes array as core values + $objarray = (array) $row; + foreach($objarray as $key => $value) { + $this->attributes[$key] = $value; } - + + return true; } /** - * Return the site specific details of a site by a row. - * - * @param int $guid + * Override the save function. */ - function get_site_entity_as_row($guid) - { - global $CONFIG; - - $guid = (int)$guid; - - /*$row = retrieve_cached_entity_row($guid); - if ($row) - { - // We have already cached this object, so retrieve its value from the cache - if (isset($CONFIG->debug) && $CONFIG->debug) - error_log("** Retrieving sub part of GUID:$guid from cache"); - - return $row; + public function save() { + // Save generic stuff + if (!parent::save()) { + return false; } - else - {*/ - // Object not cached, load it. - if (isset($CONFIG->debug) && $CONFIG->debug == true) - error_log("** Sub part of GUID:$guid loaded from DB"); - - return get_data_row("SELECT * from {$CONFIG->dbprefix}sites_entity where guid=$guid"); - //} + + // Now save specific stuff + return create_site_entity($this->get('guid'), $this->get('name'), $this->get('description'), $this->get('url')); } - + /** - * Create or update the extras table for a given site. - * Call create_entity first. - * - * @param int $guid - * @param string $name - * @param string $description - * @param string $url + * Delete this site. */ - function create_site_entity($guid, $name, $description, $url) - { + public function delete() { global $CONFIG; - - $guid = (int)$guid; - $name = sanitise_string($name); - $description = sanitise_string($description); - $url = sanitise_string($url); - - $row = get_entity_as_row($guid); - - if ($row) - { - // Exists and you have access to it - if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}sites_entity where guid = {$guid}")) { - $result = update_data("UPDATE {$CONFIG->dbprefix}sites_entity set name='$name', description='$description', url='$url' where guid=$guid"); - if ($result!=false) - { - // Update succeeded, continue - $entity = get_entity($guid); - if (trigger_elgg_event('update',$entity->type,$entity)) { - return $guid; - } else { - $entity->delete(); - //delete_entity($guid); - } - } - } - else - { - // Update failed, attempt an insert. - $result = insert_data("INSERT into {$CONFIG->dbprefix}sites_entity (guid, name, description, url) values ($guid, '$name','$description','$url')"); - if ($result!==false) { - $entity = get_entity($guid); - if (trigger_elgg_event('create',$entity->type,$entity)) { - return $guid; - } else { - $entity->delete(); - //delete_entity($guid); - } - } - } + if ($CONFIG->site->getGUID() == $this->guid) { + throw new SecurityException('SecurityException:deletedisablecurrentsite'); } - - return false; - } - - /** - * THIS FUNCTION IS DEPRECATED. - * - * Delete a site's extra data. - * - * @param int $guid - */ - function delete_site_entity($guid) - { - system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity')); - - return 1; // Always return that we have deleted one row in order to not break existing code. + + return parent::delete(); } - + /** - * Add a user to a site. - * - * @param int $site_guid - * @param int $user_guid + * Disable override to add safety rail. + * + * @param unknown_type $reason */ - function add_site_user($site_guid, $user_guid) - { + public function disable($reason = "") { global $CONFIG; - - $site_guid = (int)$site_guid; - $user_guid = (int)$user_guid; - - return add_entity_relationship($user_guid, "member_of_site", $site_guid); - } - - /** - * Remove a user from a site. - * - * @param int $site_guid - * @param int $user_guid - */ - function remove_site_user($site_guid, $user_guid) - { - $site_guid = (int)$site_guid; - $user_guid = (int)$user_guid; - - return remove_entity_relationship($user_guid, "member_of_site", $site_guid); + + if ($CONFIG->site->getGUID() == $this->guid) { + throw new SecurityException('SecurityException:deletedisablecurrentsite'); + } + + return parent::disable($reason); } - + /** - * Get the members of a site. - * - * @param int $site_guid - * @param int $limit + * Return a list of users using this site. + * + * @param int $limit * @param int $offset + * @return array of ElggUsers */ - function get_site_members($site_guid, $limit = 10, $offset = 0) - { - $site_guid = (int)$site_guid; - $limit = (int)$limit; - $offset = (int)$offset; - - return get_entities_from_relationship("member_of_site", $site_guid, true, "user", "", 0, "time_created desc", $limit, $offset); + public function getMembers($limit = 10, $offset = 0) { + get_site_members($this->getGUID(), $limit, $offset); } - + /** - * Display a list of site members + * Add a user to the site. * - * @param int $site_guid The GUID of the site - * @param int $limit The number of members to display on a page - * @param true|false $fullview Whether or not to display the full view (default: true) - * @return string A displayable list of members - */ - function list_site_members($site_guid, $limit = 10, $fullview = true) { - - $offset = (int) get_input('offset'); - $limit = (int) $limit; - $count = (int) get_entities_from_relationship("member_of_site", $site_guid, true, "user", "", 0, "time_created desc", $limit, $offset, true); - $entities = get_site_members($site_guid, $limit, $offset); - - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview); - - } - - /** - * Add an object to a site. - * - * @param int $site_guid - * @param int $object_guid + * @param int $user_guid */ - function add_site_object($site_guid, $object_guid) - { - global $CONFIG; - - $site_guid = (int)$site_guid; - $object_guid = (int)$object_guid; - - return add_entity_relationship($object_guid, "member_of_site", $site_guid); + public function addUser($user_guid) { + return add_site_user($this->getGUID(), $user_guid); } - + /** - * Remove an object from a site. - * - * @param int $site_guid - * @param int $object_guid + * Remove a site user. + * + * @param int $user_guid */ - function remove_site_object($site_guid, $object_guid) - { - $site_guid = (int)$site_guid; - $object_guid = (int)$object_guid; - - return remove_entity_relationship($object_guid, "member_of_site", $site_guid); + public function removeUser($user_guid) { + return remove_site_user($this->getGUID(), $user_guid); } - + /** - * Get the objects belonging to a site. - * - * @param int $site_guid + * Get an array of member ElggObjects. + * * @param string $subtype - * @param int $limit + * @param int $limit * @param int $offset */ - function get_site_objects($site_guid, $subtype = "", $limit = 10, $offset = 0) - { - $site_guid = (int)$site_guid; - $subtype = sanitise_string($subtype); - $limit = (int)$limit; - $offset = (int)$offset; - - return get_entities_from_relationship("member_of_site", $site_guid, true, "object", $subtype, 0, "time_created desc", $limit, $offset); + public function getObjects($subtype="", $limit = 10, $offset = 0) { + get_site_objects($this->getGUID(), $subtype, $limit, $offset); } - + /** - * Add a collection to a site. - * - * @param int $site_guid - * @param int $collection_guid + * Add an object to the site. + * + * @param int $user_id */ - function add_site_collection($site_guid, $collection_guid) - { - global $CONFIG; - - $site_guid = (int)$site_guid; - $collection_guid = (int)$collection_guid; - - return add_entity_relationship($collection_guid, "member_of_site", $site_guid); + public function addObject($object_guid) { + return add_site_object($this->getGUID(), $object_guid); } - + /** - * Remove a collection from a site. - * - * @param int $site_guid - * @param int $collection_guid + * Remove a site user. + * + * @param int $user_id */ - function remove_site_collection($site_guid, $collection_guid) - { - $site_guid = (int)$site_guid; - $collection_guid = (int)$collection_guid; - - return remove_entity_relationship($collection_guid, "member_of_site", $site_guid); + public function removeObject($object_guid) { + return remove_site_object($this->getGUID(), $object_guid); } - + /** - * Get the collections belonging to a site. - * - * @param int $site_guid - * @param string $subtype - * @param int $limit + * Get the collections associated with a site. + * + * @param string $type + * @param int $limit * @param int $offset + * @return unknown */ - function get_site_collections($site_guid, $subtype = "", $limit = 10, $offset = 0) - { - $site_guid = (int)$site_guid; - $subtype = sanitise_string($subtype); - $limit = (int)$limit; - $offset = (int)$offset; - - return get_entities_from_relationship("member_of_site", $site_guid, true, "collection", $subtype, 0, "time_created desc", $limit, $offset); + public function getCollections($subtype="", $limit = 10, $offset = 0) { + get_site_collections($this->getGUID(), $subtype, $limit, $offset); } - + + // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// + /** - * Return the site via a url. + * Return an array of fields which can be exported. */ - function get_site_by_url($url) - { - global $CONFIG; - - $url = sanitise_string($url); - - $row = get_data_row("SELECT * from {$CONFIG->dbprefix}sites_entity where url='$url'"); - - if ($row) - return new ElggSite($row); - - return false; + public function getExportableValues() { + return array_merge(parent::getExportableValues(), array( + 'name', + 'description', + 'url', + )); } - - /** - * Searches for a site based on a complete or partial name or description or url using full text searching. - * - * IMPORTANT NOTE: With MySQL's default setup: - * 1) $criteria must be 4 or more characters long - * 2) If $criteria matches greater than 50% of results NO RESULTS ARE RETURNED! - * - * @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. - */ - function search_for_site($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) +} + +/** + * Return the site specific details of a site by a row. + * + * @param int $guid + */ +function get_site_entity_as_row($guid) { + global $CONFIG; + + $guid = (int)$guid; + + /*$row = retrieve_cached_entity_row($guid); + if ($row) { - global $CONFIG; - - $criteria = sanitise_string($criteria); - $limit = (int)$limit; - $offset = (int)$offset; - $order_by = sanitise_string($order_by); - - $access = get_access_sql_suffix("e"); - - 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 join {$CONFIG->dbprefix}sites_entity s on e.guid=s.guid where match(s.name,s.description,s.url) against ('$criteria') and $access"; - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); + // We have already cached this object, so retrieve its value from the cache + if (isset($CONFIG->debug) && $CONFIG->debug) + error_log("** Retrieving sub part of GUID:$guid from cache"); + + return $row; + } + else + {*/ + // Object not cached, load it. + if (isset($CONFIG->debug) && $CONFIG->debug == true) { + error_log("** Sub part of GUID:$guid loaded from DB"); + } + + return get_data_row("SELECT * from {$CONFIG->dbprefix}sites_entity where guid=$guid"); + //} +} + +/** + * Create or update the extras table for a given site. + * Call create_entity first. + * + * @param int $guid + * @param string $name + * @param string $description + * @param string $url + */ +function create_site_entity($guid, $name, $description, $url) { + global $CONFIG; + + $guid = (int)$guid; + $name = sanitise_string($name); + $description = sanitise_string($description); + $url = sanitise_string($url); + + $row = get_entity_as_row($guid); + + if ($row) { + // Exists and you have access to it + if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}sites_entity where guid = {$guid}")) { + $result = update_data("UPDATE {$CONFIG->dbprefix}sites_entity set name='$name', description='$description', url='$url' where guid=$guid"); + if ($result!=false) { + // Update succeeded, continue + $entity = get_entity($guid); + if (trigger_elgg_event('update',$entity->type,$entity)) { + return $guid; + } else { + $entity->delete(); + //delete_entity($guid); + } + } } else { - if ($count = get_data_row($query)) { - return $count->total; + // Update failed, attempt an insert. + $result = insert_data("INSERT into {$CONFIG->dbprefix}sites_entity (guid, name, description, url) values ($guid, '$name','$description','$url')"); + if ($result!==false) { + $entity = get_entity($guid); + if (trigger_elgg_event('create',$entity->type,$entity)) { + return $guid; + } else { + $entity->delete(); + //delete_entity($guid); + } } } - return false; } - - /** - * Retrieve a site and return the domain portion of its url. - * - * @param int $guid - */ - function get_site_domain($guid) - { - $guid = (int)$guid; - - $site = get_entity($guid); - if ($site instanceof ElggSite) { - $breakdown = parse_url($site->url); - return $breakdown['host']; + + return false; +} + +/** + * THIS FUNCTION IS DEPRECATED. + * + * Delete a site's extra data. + * + * @param int $guid + */ +function delete_site_entity($guid) { + system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity')); + + return 1; // Always return that we have deleted one row in order to not break existing code. +} + +/** + * Add a user to a site. + * + * @param int $site_guid + * @param int $user_guid + */ +function add_site_user($site_guid, $user_guid) { + global $CONFIG; + + $site_guid = (int)$site_guid; + $user_guid = (int)$user_guid; + + return add_entity_relationship($user_guid, "member_of_site", $site_guid); +} + +/** + * Remove a user from a site. + * + * @param int $site_guid + * @param int $user_guid + */ +function remove_site_user($site_guid, $user_guid) { + $site_guid = (int)$site_guid; + $user_guid = (int)$user_guid; + + return remove_entity_relationship($user_guid, "member_of_site", $site_guid); +} + +/** + * Get the members of a site. + * + * @param int $site_guid + * @param int $limit + * @param int $offset + */ +function get_site_members($site_guid, $limit = 10, $offset = 0) { + $site_guid = (int)$site_guid; + $limit = (int)$limit; + $offset = (int)$offset; + + return get_entities_from_relationship("member_of_site", $site_guid, true, "user", "", 0, "time_created desc", $limit, $offset); +} + +/** + * Display a list of site members + * + * @param int $site_guid The GUID of the site + * @param int $limit The number of members to display on a page + * @param true|false $fullview Whether or not to display the full view (default: true) + * @return string A displayable list of members + */ +function list_site_members($site_guid, $limit = 10, $fullview = true) { + $offset = (int) get_input('offset'); + $limit = (int) $limit; + $count = (int) get_entities_from_relationship("member_of_site", $site_guid, true, "user", "", 0, "time_created desc", $limit, $offset, true); + $entities = get_site_members($site_guid, $limit, $offset); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview); + +} + +/** + * Add an object to a site. + * + * @param int $site_guid + * @param int $object_guid + */ +function add_site_object($site_guid, $object_guid) { + global $CONFIG; + + $site_guid = (int)$site_guid; + $object_guid = (int)$object_guid; + + return add_entity_relationship($object_guid, "member_of_site", $site_guid); +} + +/** + * Remove an object from a site. + * + * @param int $site_guid + * @param int $object_guid + */ +function remove_site_object($site_guid, $object_guid) { + $site_guid = (int)$site_guid; + $object_guid = (int)$object_guid; + + return remove_entity_relationship($object_guid, "member_of_site", $site_guid); +} + +/** + * Get the objects belonging to a site. + * + * @param int $site_guid + * @param string $subtype + * @param int $limit + * @param int $offset + */ +function get_site_objects($site_guid, $subtype = "", $limit = 10, $offset = 0) { + $site_guid = (int)$site_guid; + $subtype = sanitise_string($subtype); + $limit = (int)$limit; + $offset = (int)$offset; + + return get_entities_from_relationship("member_of_site", $site_guid, true, "object", $subtype, 0, "time_created desc", $limit, $offset); +} + +/** + * Add a collection to a site. + * + * @param int $site_guid + * @param int $collection_guid + */ +function add_site_collection($site_guid, $collection_guid) { + global $CONFIG; + + $site_guid = (int)$site_guid; + $collection_guid = (int)$collection_guid; + + return add_entity_relationship($collection_guid, "member_of_site", $site_guid); +} + +/** + * Remove a collection from a site. + * + * @param int $site_guid + * @param int $collection_guid + */ +function remove_site_collection($site_guid, $collection_guid) { + $site_guid = (int)$site_guid; + $collection_guid = (int)$collection_guid; + + return remove_entity_relationship($collection_guid, "member_of_site", $site_guid); +} + +/** + * Get the collections belonging to a site. + * + * @param int $site_guid + * @param string $subtype + * @param int $limit + * @param int $offset + */ +function get_site_collections($site_guid, $subtype = "", $limit = 10, $offset = 0) { + $site_guid = (int)$site_guid; + $subtype = sanitise_string($subtype); + $limit = (int)$limit; + $offset = (int)$offset; + + return get_entities_from_relationship("member_of_site", $site_guid, true, "collection", $subtype, 0, "time_created desc", $limit, $offset); +} + +/** + * Return the site via a url. + */ +function get_site_by_url($url) { + global $CONFIG; + + $url = sanitise_string($url); + + $row = get_data_row("SELECT * from {$CONFIG->dbprefix}sites_entity where url='$url'"); + + if ($row) { + return new ElggSite($row); + } + + return false; +} + +/** + * Searches for a site based on a complete or partial name or description or url using full text searching. + * + * IMPORTANT NOTE: With MySQL's default setup: + * 1) $criteria must be 4 or more characters long + * 2) If $criteria matches greater than 50% of results NO RESULTS ARE RETURNED! + * + * @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. + */ +function search_for_site($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) { + global $CONFIG; + + $criteria = sanitise_string($criteria); + $limit = (int)$limit; + $offset = (int)$offset; + $order_by = sanitise_string($order_by); + + $access = get_access_sql_suffix("e"); + + 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 join {$CONFIG->dbprefix}sites_entity s on e.guid=s.guid where match(s.name,s.description,s.url) against ('$criteria') and $access"; + + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; } - - return false; } - - /** - * Initialise site handling - * - * Called at the beginning of system running, to set the ID of the current site. - * This is 0 by default, but plugins may alter this behaviour by attaching functions - * to the sites init event and changing $CONFIG->site_id. - * - * @uses $CONFIG - * @param string $event Event API required parameter - * @param string $object_type Event API required parameter - * @param null $object Event API required parameter - * @return true - */ - function sites_init($event, $object_type, $object) { - - global $CONFIG; - - if (is_installed() && is_db_installed()) { - - $site = trigger_plugin_hook("siteid","system"); - if ($site === null || $site === false) { - $CONFIG->site_id = (int) datalist_get('default_site'); - } else { - $CONFIG->site_id = $site; - } - $CONFIG->site_guid = $CONFIG->site_id; - $CONFIG->site = get_entity($CONFIG->site_guid); - - return true; - } - - return true; + return false; +} + +/** + * Retrieve a site and return the domain portion of its url. + * + * @param int $guid + */ +function get_site_domain($guid) { + $guid = (int)$guid; + + $site = get_entity($guid); + if ($site instanceof ElggSite) { + $breakdown = parse_url($site->url); + return $breakdown['host']; + } + + return false; +} + +/** + * Initialise site handling + * + * Called at the beginning of system running, to set the ID of the current site. + * This is 0 by default, but plugins may alter this behaviour by attaching functions + * to the sites init event and changing $CONFIG->site_id. + * + * @uses $CONFIG + * @param string $event Event API required parameter + * @param string $object_type Event API required parameter + * @param null $object Event API required parameter + * @return true + */ +function sites_init($event, $object_type, $object) { + global $CONFIG; + + if (is_installed() && is_db_installed()) { + $site = trigger_plugin_hook("siteid","system"); + if ($site === null || $site === false) { + $CONFIG->site_id = (int) datalist_get('default_site'); + } else { + $CONFIG->site_id = $site; } - - // Register event handlers - register_elgg_event_handler('boot','system','sites_init',2); - - // Register with unit test - register_plugin_hook('unit_test', 'system', 'sites_test'); - function sites_test($hook, $type, $value, $params) { - global $CONFIG; - $value[] = "{$CONFIG->path}engine/tests/objects/sites.php"; - return $value; + $CONFIG->site_guid = $CONFIG->site_id; + $CONFIG->site = get_entity($CONFIG->site_guid); + + return true; } + + return true; +} + +// Register event handlers +register_elgg_event_handler('boot','system','sites_init',2); + +// Register with unit test +register_plugin_hook('unit_test', 'system', 'sites_test'); +function sites_test($hook, $type, $value, $params) { + global $CONFIG; + $value[] = "{$CONFIG->path}engine/tests/objects/sites.php"; + return $value; +} diff --git a/engine/lib/social.php b/engine/lib/social.php index e8bfccda5..381c7ea4f 100644 --- a/engine/lib/social.php +++ b/engine/lib/social.php @@ -1,128 +1,119 @@ wordblacklist)) - return $input; - - if (strlen($input) < 3 || in_array($input,$CONFIG->wordblacklist)) - return false; - - return true; - - } - + // Explode it into an array + $terms = explode(' ',$string); - /** - * Initialise. - * - * Sets a blacklist of words in the current language. This is a comma separated list in word:blacklist. - */ - function social_init() { - global $CONFIG; - - $CONFIG->wordblacklist = array(); - - $list = explode(',', elgg_echo('word:blacklist')); - if ($list) - { - foreach ($list as $l) - $CONFIG->wordblacklist[] = trim($l); - } - else - { - // Fallback - shouldn't happen - $CONFIG->wordblacklist = array( - 'and', - 'the', - 'then', - 'but', - 'she', - 'his', - 'her', - 'him', - 'one', - 'not', - 'also', - 'about', - 'now', - 'hence', - 'however', - 'still', - 'likewise', - 'otherwise', - 'therefore', - 'conversely', - 'rather', - 'consequently', - 'furthermore', - 'nevertheless', - 'instead', - 'meanwhile', - 'accordingly', - 'this', - 'seems', - 'what', - 'whom', - 'whose', - 'whoever', - 'whomever', - ); - } - } + // Remove any blacklist terms + //$terms = array_filter($terms, 'remove_blacklist'); - register_elgg_event_handler("init","system","social_init"); - -?> \ No newline at end of file + return $terms; +} + +/** + * Returns true if the word in $input is considered significant + * + * @param string $input + * @return true|false + */ +function remove_blacklist($input) { + global $CONFIG; + + if (!is_array($CONFIG->wordblacklist)) { + return $input; + } + + if (strlen($input) < 3 || in_array($input,$CONFIG->wordblacklist)) { + return false; + } + + return true; +} + + +/** + * Initialise. + * + * Sets a blacklist of words in the current language. This is a comma separated list in word:blacklist. + */ +function social_init() { + global $CONFIG; + + $CONFIG->wordblacklist = array(); + + $list = explode(',', elgg_echo('word:blacklist')); + if ($list) { + foreach ($list as $l) { + $CONFIG->wordblacklist[] = trim($l); + } + } else { + // Fallback - shouldn't happen + $CONFIG->wordblacklist = array( + 'and', + 'the', + 'then', + 'but', + 'she', + 'his', + 'her', + 'him', + 'one', + 'not', + 'also', + 'about', + 'now', + 'hence', + 'however', + 'still', + 'likewise', + 'otherwise', + 'therefore', + 'conversely', + 'rather', + 'consequently', + 'furthermore', + 'nevertheless', + 'instead', + 'meanwhile', + 'accordingly', + 'this', + 'seems', + 'what', + 'whom', + 'whose', + 'whoever', + 'whomever', + ); + } +} + +register_elgg_event_handler("init","system","social_init"); \ No newline at end of file diff --git a/engine/lib/statistics.php b/engine/lib/statistics.php index 24d2e4155..b8bf2b012 100644 --- a/engine/lib/statistics.php +++ b/engine/lib/statistics.php @@ -1,110 +1,109 @@ dbprefix}entities e left join {$CONFIG->dbprefix}entity_subtypes s on e.subtype=s.id"; - $owner_query = ""; - if ($owner_guid) { - $query .= " where owner_guid=$owner_guid"; - $owner_query = "and owner_guid=$owner_guid "; +/** + * Elgg statistics library. + * This file contains a number of functions for obtaining statistics about the running system. + * These statistics are mainly used by the administration pages, and is also where the basic views for statistics + * are added. + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + */ + +/** + * Return an array reporting the number of various entities in the system. + * + * @param int $owner_guid Optional owner of the statistics + * @return array + */ +function get_entity_statistics($owner_guid = 0) { + global $CONFIG; + + $entity_stats = array(); + $owner_guid = (int)$owner_guid; + + $query = "SELECT distinct e.type,s.subtype,e.subtype as subtype_id from {$CONFIG->dbprefix}entities e left join {$CONFIG->dbprefix}entity_subtypes s on e.subtype=s.id"; + $owner_query = ""; + if ($owner_guid) { + $query .= " where owner_guid=$owner_guid"; + $owner_query = "and owner_guid=$owner_guid "; + } + + // Get a list of major types + + $types = get_data($query); + foreach ($types as $type) { + // assume there are subtypes for now + if (!is_array($entity_stats[$type->type])) { + $entity_stats[$type->type] = array(); + } + + $query = "SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='{$type->type}' $owner_query"; + if ($type->subtype) { + $query.= " and subtype={$type->subtype_id}"; } - - // Get a list of major types - - $types = get_data($query); - foreach ($types as $type) { - if (!is_array($entity_stats[$type->type])) - $entity_stats[$type->type] = array(); // assume there are subtypes for now - - $query = "SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='{$type->type}' $owner_query"; - if ($type->subtype) $query.= " and subtype={$type->subtype_id}"; - - $subtype_cnt = get_data_row($query); - - if ($type->subtype) - $entity_stats[$type->type][$type->subtype] = $subtype_cnt->count; - else - $entity_stats[$type->type]['__base__'] = $subtype_cnt->count; + + $subtype_cnt = get_data_row($query); + + if ($type->subtype) { + $entity_stats[$type->type][$type->subtype] = $subtype_cnt->count; + } else { + $entity_stats[$type->type]['__base__'] = $subtype_cnt->count; } - - return $entity_stats; } - - /** - * Return the number of users registered in the system. - * - * @param bool $show_deactivated - * @return int - */ - function get_number_users($show_deactivated = false) - { - global $CONFIG; - - $access = ""; - - if (!$show_deactivated) - $access = "and " . get_access_sql_suffix(); - - $result = get_data_row("SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='user' $access"); - - if ($result) - return $result->count; - - return false; + + return $entity_stats; +} + +/** + * Return the number of users registered in the system. + * + * @param bool $show_deactivated + * @return int + */ +function get_number_users($show_deactivated = false) { + global $CONFIG; + + $access = ""; + + if (!$show_deactivated) { + $access = "and " . get_access_sql_suffix(); } - - /** - * Return a list of how many users are currently online, rendered as a view. - */ - function get_online_users() - { - $offset = get_input('offset',0); - $count = count(find_active_users(600,9999)); - $objects = find_active_users(600,10,$offset); - - if ($objects) - { - return elgg_view_entity_list($objects, $count,$offset,10,false); - } + + $result = get_data_row("SELECT count(*) as count from {$CONFIG->dbprefix}entities where type='user' $access"); + + if ($result) { + return $result->count; } - - /** - * Initialise the statistics admin page. - */ - function statistics_init() - { - extend_elgg_admin_page('admin/statistics_opt/basic', 'admin/statistics'); - extend_elgg_admin_page('admin/statistics_opt/numentities', 'admin/statistics'); - extend_elgg_admin_page('admin/statistics_opt/online', 'admin/statistics'); - - - - extend_elgg_settings_page('usersettings/statistics_opt/online', 'usersettings/statistics'); - extend_elgg_settings_page('usersettings/statistics_opt/numentities', 'usersettings/statistics'); + + return false; +} + +/** + * Return a list of how many users are currently online, rendered as a view. + */ +function get_online_users() { + $offset = get_input('offset', 0); + $count = count(find_active_users(600, 9999)); + $objects = find_active_users(600, 10, $offset); + + if ($objects) { + return elgg_view_entity_list($objects, $count,$offset,10,false); } - - /// Register init function - register_elgg_event_handler('init','system','statistics_init'); -?> +} + +/** + * Initialise the statistics admin page. + */ +function statistics_init() { + extend_elgg_admin_page('admin/statistics_opt/basic', 'admin/statistics'); + extend_elgg_admin_page('admin/statistics_opt/numentities', 'admin/statistics'); + extend_elgg_admin_page('admin/statistics_opt/online', 'admin/statistics'); + + extend_elgg_settings_page('usersettings/statistics_opt/online', 'usersettings/statistics'); + extend_elgg_settings_page('usersettings/statistics_opt/numentities', 'usersettings/statistics'); +} + +/// Register init function +register_elgg_event_handler('init','system','statistics_init'); \ No newline at end of file diff --git a/engine/lib/system_log.php b/engine/lib/system_log.php index dd32602be..75a7cc531 100644 --- a/engine/lib/system_log.php +++ b/engine/lib/system_log.php @@ -1,297 +1,302 @@ 0) { - foreach($by_user as $key => $val) { - $by_user[$key] = (int) $val; - } - } else { - $by_user = (int)$by_user; - } - $event = sanitise_string($event); - $class = sanitise_string($class); - $type = sanitise_string($type); - $subtype = sanitise_string($subtype); - $limit = (int)$limit; - $offset = (int)$offset; - - $where = array(); - - if ($by_user_orig!=="") - { - if (is_int($by_user)) { - $where[] = "performed_by_guid=$by_user"; - } else if (is_array($by_user)) { - $where [] = "performed_by_guid in (". implode(",",$by_user) .")"; - } - } - if ($event != "") - $where[] = "event='$event'"; - if ($class!=="") - $where[] = "object_class='$class'"; - if ($type != "") - $where[] = "object_type='$type'"; - if ($subtype!=="") - $where[] = "object_subtype='$subtype'"; - - if ($timebefore) - $where[] = "time_created < " . ((int) $timebefore); - if ($timeafter) - $where[] = "time_created > " . ((int) $timeafter); - if ($object_id) - $where[] = "object_id = " . ((int) $object_id); - - $select = "*"; - if ($count) $select = "count(*) as count"; - $query = "SELECT $select from {$CONFIG->dbprefix}system_log where 1 "; - foreach ($where as $w) - $query .= " and $w"; - - if (!$count) - { - $query .= " order by time_created desc"; - $query .= " limit $offset, $limit"; // Add order and limit - } - - if ($count) - { - if ($numrows = get_data_row($query)) - return $numrows->count; - } - else - return get_data($query); - - return false; - } - + public function getType(); + /** - * Return a specific log entry. - * - * @param int $entry_id The log entry + * Return a subtype. For metadata & annotations this is the 'name' and for relationship this is the relationship type. */ - function get_log_entry($entry_id) - { - global $CONFIG; - - $entry_id = (int)$entry_id; - - return get_data_row("SELECT * from {$CONFIG->dbprefix}system_log where id=$entry_id"); - } - + public function getSubtype(); + /** - * Return the object referred to by a given log entry - * - * @param int $entry_id The log entry + * For a given ID, return the object associated with it. + * This is used by the river functionality primarily. + * This is useful for checking access permissions etc on objects. */ - function get_object_from_log_entry($entry_id) - { - $entry = get_log_entry($entry_id); - - if ($entry) - { - $class = $entry->object_class; - $tmp = new $class(); - $object = $tmp->getObjectFromID($entry->object_id); - - if ($object) - return $object; - } - - return false; - } - + public function getObjectFromID($id); + /** - * Log a system event related to a specific object. - * - * This is called by the event system and should not be called directly. - * - * @param $object The object you're talking about. - * @param $event String The event being logged + * Return the GUID of the owner of this object. */ - function system_log($object, $event) - { - global $CONFIG; - static $logcache; - - if ($object instanceof Loggable) - { - - if (!is_array($logcache)) $logcache = array(); - - // Has loggable interface, extract the necessary information and store - $object_id = (int)$object->getSystemLogID(); - $object_class = $object->getClassName(); - $object_type = $object->getType(); - $object_subtype = $object->getSubtype(); - $event = sanitise_string($event); - $time = time(); - $performed_by = (int)$_SESSION['guid']; - - if (isset($object->access_id)) - $access_id = $object->access_id; - else - $access_id = ACCESS_PUBLIC; - if (isset($object->enabled)) - $enabled = $object->enabled; - else - $enabled = 'yes'; - - if (isset($object->owner_guid)) - $owner_guid = $object->owner_guid; - else - $owner_guid = 0; - - // Create log if we haven't already created it - if (!isset($logcache[$time][$object_id][$event])) { - insert_data("INSERT DELAYED into {$CONFIG->dbprefix}system_log (object_id, object_class, object_type, object_subtype, event, performed_by_guid, owner_guid, access_id, enabled, time_created) VALUES ('$object_id','$object_class','$object_type', '$object_subtype', '$event',$performed_by, $owner_guid, $access_id, '$enabled', '$time')"); - - $logcache[$time][$object_id][$event] = true; - } - - return true; - + public function getObjectOwnerGUID(); +} + +/** + * Retrieve the system log based on a number of parameters. + * + * @param int or array $by_user The guid(s) of the user(s) who initiated the event. + * @param string $event The event you are searching on. + * @param string $class The class of object it effects. + * @param string $type The type + * @param string $subtype The subtype. + * @param int $limit Maximum number of responses to return. + * @param int $offset Offset of where to start. + * @param bool $count Return count or not + */ +function get_system_log($by_user = "", $event = "", $class = "", $type = "", $subtype = "", $limit = 10, $offset = 0, $count = false, $timebefore = 0, $timeafter = 0, $object_id = 0) { + global $CONFIG; + + $by_user_orig = $by_user; + if (is_array($by_user) && sizeof($by_user) > 0) { + foreach($by_user as $key => $val) { + $by_user[$key] = (int) $val; } + } else { + $by_user = (int)$by_user; } - - /** - * This function creates an archive copy of the system log. - * - * @param int $offset An offset in seconds from now to archive (useful for log rotation) - */ - function archive_log($offset = 0) - { - global $CONFIG; - - $offset = (int)$offset; - $now = time(); // Take a snapshot of now - - $ts = $now - $offset; - - // create table - if (!update_data("CREATE TABLE {$CONFIG->dbprefix}system_log_$now as SELECT * from {$CONFIG->dbprefix}system_log WHERE time_created<$ts")) - return false; - - // delete - if (delete_data("DELETE from {$CONFIG->dbprefix}system_log WHERE time_created<$ts")===false) // Don't delete on time since we are running in a concurrent environment - return false; - - // alter table to engine - if (!update_data("ALTER TABLE {$CONFIG->dbprefix}system_log_$now engine=archive")) - return false; - - return true; + $event = sanitise_string($event); + $class = sanitise_string($class); + $type = sanitise_string($type); + $subtype = sanitise_string($subtype); + $limit = (int)$limit; + $offset = (int)$offset; + + $where = array(); + + if ($by_user_orig!=="") { + if (is_int($by_user)) { + $where[] = "performed_by_guid=$by_user"; + } else if (is_array($by_user)) { + $where [] = "performed_by_guid in (". implode(",",$by_user) .")"; + } } - - /** - * Default system log handler, allows plugins to override, extend or disable logging. - * - * @param string $event - * @param string $object_type - * @param Loggable $object - * @return unknown - */ - function system_log_default_logger($event, $object_type, $object) - { - system_log($object['object'], $object['event']); - - return true; + if ($event != "") { + $where[] = "event='$event'"; } - - /** - * System log listener. - * This function listens to all events in the system and logs anything appropriate. - * - * @param String $event - * @param String $object_type - * @param Loggable $object - */ - function system_log_listener($event, $object_type, $object) - { - if (($object_type!='systemlog') && ($event!='log')) - trigger_elgg_event('log', 'systemlog', array('object' => $object, 'event' => $event)); - + if ($class!=="") { + $where[] = "object_class='$class'"; + } + if ($type != "") { + $where[] = "object_type='$type'"; + } + if ($subtype!=="") { + $where[] = "object_subtype='$subtype'"; + } + + if ($timebefore) { + $where[] = "time_created < " . ((int) $timebefore); + } + if ($timeafter) { + $where[] = "time_created > " . ((int) $timeafter); + } + if ($object_id) { + $where[] = "object_id = " . ((int) $object_id); + } + + $select = "*"; + if ($count) { + $select = "count(*) as count"; + } + $query = "SELECT $select from {$CONFIG->dbprefix}system_log where 1 "; + foreach ($where as $w) { + $query .= " and $w"; + } + + if (!$count) { + $query .= " order by time_created desc"; + $query .= " limit $offset, $limit"; // Add order and limit + } + + if ($count) { + if ($numrows = get_data_row($query)) { + return $numrows->count; + } + } else { + return get_data($query); + } + + return false; +} + +/** + * Return a specific log entry. + * + * @param int $entry_id The log entry + */ +function get_log_entry($entry_id) { + global $CONFIG; + + $entry_id = (int)$entry_id; + + return get_data_row("SELECT * from {$CONFIG->dbprefix}system_log where id=$entry_id"); +} + +/** + * Return the object referred to by a given log entry + * + * @param int $entry_id The log entry + */ +function get_object_from_log_entry($entry_id) { + $entry = get_log_entry($entry_id); + + if ($entry) { + $class = $entry->object_class; + $tmp = new $class(); + $object = $tmp->getObjectFromID($entry->object_id); + + if ($object) { + return $object; + } + } + + return false; +} + +/** + * Log a system event related to a specific object. + * + * This is called by the event system and should not be called directly. + * + * @param $object The object you're talking about. + * @param $event String The event being logged + */ +function system_log($object, $event) { + global $CONFIG; + static $logcache; + + if ($object instanceof Loggable) { + if (!is_array($logcache)) { + $logcache = array(); + } + + // Has loggable interface, extract the necessary information and store + $object_id = (int)$object->getSystemLogID(); + $object_class = $object->getClassName(); + $object_type = $object->getType(); + $object_subtype = $object->getSubtype(); + $event = sanitise_string($event); + $time = time(); + $performed_by = (int)$_SESSION['guid']; + + if (isset($object->access_id)) { + $access_id = $object->access_id; + } else { + $access_id = ACCESS_PUBLIC; + } + if (isset($object->enabled)) { + $enabled = $object->enabled; + } else { + $enabled = 'yes'; + } + + if (isset($object->owner_guid)) { + $owner_guid = $object->owner_guid; + } else { + $owner_guid = 0; + } + + // Create log if we haven't already created it + if (!isset($logcache[$time][$object_id][$event])) { + insert_data("INSERT DELAYED into {$CONFIG->dbprefix}system_log (object_id, object_class, object_type, object_subtype, event, performed_by_guid, owner_guid, access_id, enabled, time_created) VALUES ('$object_id','$object_class','$object_type', '$object_subtype', '$event',$performed_by, $owner_guid, $access_id, '$enabled', '$time')"); + + $logcache[$time][$object_id][$event] = true; + } + return true; } - - /** Register event to listen to all events **/ - register_elgg_event_handler('all','all','system_log_listener', 400); - - /** Register a default system log handler */ - register_elgg_event_handler('log','systemlog','system_log_default_logger', 999); - -?> \ No newline at end of file +} + +/** + * This function creates an archive copy of the system log. + * + * @param int $offset An offset in seconds from now to archive (useful for log rotation) + */ +function archive_log($offset = 0) { + global $CONFIG; + + $offset = (int)$offset; + $now = time(); // Take a snapshot of now + + $ts = $now - $offset; + + // create table + if (!update_data("CREATE TABLE {$CONFIG->dbprefix}system_log_$now as SELECT * from {$CONFIG->dbprefix}system_log WHERE time_created<$ts")) { + return false; + } + + // delete + // Don't delete on time since we are running in a concurrent environment + if (delete_data("DELETE from {$CONFIG->dbprefix}system_log WHERE time_created<$ts") === false) { + return false; + } + + // alter table to engine + if (!update_data("ALTER TABLE {$CONFIG->dbprefix}system_log_$now engine=archive")) { + return false; + } + + return true; +} + +/** + * Default system log handler, allows plugins to override, extend or disable logging. + * + * @param string $event + * @param string $object_type + * @param Loggable $object + * @return unknown + */ +function system_log_default_logger($event, $object_type, $object) { + system_log($object['object'], $object['event']); + + return true; +} + +/** + * System log listener. + * This function listens to all events in the system and logs anything appropriate. + * + * @param String $event + * @param String $object_type + * @param Loggable $object + */ +function system_log_listener($event, $object_type, $object) { + if (($object_type!='systemlog') && ($event!='log')) { + trigger_elgg_event('log', 'systemlog', array('object' => $object, 'event' => $event)); + } + + return true; +} + +/** Register event to listen to all events **/ +register_elgg_event_handler('all','all','system_log_listener', 400); + +/** Register a default system log handler */ +register_elgg_event_handler('log','systemlog','system_log_default_logger', 999); \ No newline at end of file diff --git a/engine/lib/tags.php b/engine/lib/tags.php index d3db842d1..3c65c2a7a 100644 --- a/engine/lib/tags.php +++ b/engine/lib/tags.php @@ -1,176 +1,177 @@ - - * @link http://elgg.org/ - */ - - - /** - * The algorithm working out the size of font based on the number of tags. - * This is quick and dirty. - */ - function calculate_tag_size($min, $max, $number_of_tags, $buckets = 6) - { - - $delta = (($max - $min) / $buckets); - $thresholds = array(); - - for ($n=1; $n <= $buckets; $n++) { - $thresholds[$n-1] = ($min + $n) * $delta; - } - - // Correction - if ($thresholds[$buckets-1]>$max) $thresholds[$buckets-1] = $max; - - $size = 0; - for ($n = 0; $n < count($thresholds); $n++) { - if ($number_of_tags >= $thresholds[$n]) - $size = $n; +/** + * Elgg tags + * Functions for managing tags and tag clouds. + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + */ + + +/** + * The algorithm working out the size of font based on the number of tags. + * This is quick and dirty. + */ +function calculate_tag_size($min, $max, $number_of_tags, $buckets = 6) { + + $delta = (($max - $min) / $buckets); + $thresholds = array(); + + for ($n=1; $n <= $buckets; $n++) { + $thresholds[$n-1] = ($min + $n) * $delta; + } + + // Correction + if ($thresholds[$buckets-1]>$max) { + $thresholds[$buckets-1] = $max; + } + + $size = 0; + for ($n = 0; $n < count($thresholds); $n++) { + if ($number_of_tags >= $thresholds[$n]) { + $size = $n; } + } + + return $size; +} + +/** + * This function generates an array of tags with a weighting. + * + * @param array $tags The array of tags. + * @return An associated array of tags with a weighting, this can then be mapped to a display class. + */ +function generate_tag_cloud(array $tags, $buckets = 6) { + $cloud = array(); + + $min = 65535; + $max = 0; + + foreach ($tags as $tag) { + $cloud[$tag]++; - return $size; - } - - /** - * This function generates an array of tags with a weighting. - * - * @param array $tags The array of tags. - * @return An associated array of tags with a weighting, this can then be mapped to a display class. - */ - function generate_tag_cloud(array $tags, $buckets = 6) - { - $cloud = array(); - - $min = 65535; - $max = 0; - - foreach ($tags as $tag) - { - $cloud[$tag]++; - - if ($cloud[$tag]>$max) $max = $cloud[$tag]; - if ($cloud[$tag]<$min) $min = $cloud[$tag]; + if ($cloud[$tag]>$max) { + $max = $cloud[$tag]; } - - foreach ($cloud as $k => $v) - $cloud[$k] = calculate_tag_size($min, $max, $v, $buckets); - - return $cloud; - } - - /** - * Get an array of tags with weights for use with the output/tagcloud view. - * - * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances) - * @param int $limit Number of tags to return - * @param string $metadata_name Optionally, the name of the field you want to grab for - * @param string $entity_type Optionally, the entity type ('object' etc) - * @param string $entity_subtype The entity subtype, optionally - * @param int $owner_guid The GUID of the tags owner, optionally - * @param int $site_guid Optionally, the site to restrict to (default is the current site) - * @param int $start_ts Optionally specify a start timestamp for tags used to generate cloud. - * @param int $ent_ts Optionally specify an end timestamp for tags used to generate cloud. - * @return array|false Array of objects with ->tag and ->total values, or false on failure - */ - - function get_tags($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1, $start_ts = "", $end_ts = "") { - - global $CONFIG; - - $threshold = (int) $threshold; - $limit = (int) $limit; - - if (!empty($metadata_name)) { - $metadata_name = (int) get_metastring_id($metadata_name); - } else { - $metadata_name = 0; + + if ($cloud[$tag]<$min) { + $min = $cloud[$tag]; } - $entity_subtype = get_subtype_id($entity_type, $entity_subtype); - $entity_type = sanitise_string($entity_type); - - if ($owner_guid != "") + } + + foreach ($cloud as $k => $v) { + $cloud[$k] = calculate_tag_size($min, $max, $v, $buckets); + } + + return $cloud; +} + +/** + * Get an array of tags with weights for use with the output/tagcloud view. + * + * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances) + * @param int $limit Number of tags to return + * @param string $metadata_name Optionally, the name of the field you want to grab for + * @param string $entity_type Optionally, the entity type ('object' etc) + * @param string $entity_subtype The entity subtype, optionally + * @param int $owner_guid The GUID of the tags owner, optionally + * @param int $site_guid Optionally, the site to restrict to (default is the current site) + * @param int $start_ts Optionally specify a start timestamp for tags used to generate cloud. + * @param int $ent_ts Optionally specify an end timestamp for tags used to generate cloud. + * @return array|false Array of objects with ->tag and ->total values, or false on failure + */ + +function get_tags($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1, $start_ts = "", $end_ts = "") { + global $CONFIG; + + $threshold = (int) $threshold; + $limit = (int) $limit; + + if (!empty($metadata_name)) { + $metadata_name = (int) get_metastring_id($metadata_name); + } else { + $metadata_name = 0; + } + $entity_subtype = get_subtype_id($entity_type, $entity_subtype); + $entity_type = sanitise_string($entity_type); + + if ($owner_guid != "") { if (is_array($owner_guid)) { - foreach($owner_guid as $key => $val) + foreach($owner_guid as $key => $val) { $owner_guid[$key] = (int) $val; + } } else { $owner_guid = (int) $owner_guid; } - - if ($site_guid < 0) { - $site_guid = $CONFIG->site_id; - } - - //$access = get_access_list(); - - $query = "SELECT msvalue.string as tag, count(msvalue.id) as total "; - $query .= "FROM {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}metadata md on md.entity_guid = e.guid "; - if ($entity_subtype > 0) - $query .= " join {$CONFIG->dbprefix}entity_subtypes subtype on subtype.id = e.subtype "; - $query .= " join {$CONFIG->dbprefix}metastrings msvalue on msvalue.id = md.value_id "; - - $query .= " where msvalue.string != '' "; - - if ($metadata_name > 0) { - $query .= " and md.name_id = {$metadata_name} "; - } - if ($site_guid > 0) { - $query .= " and e.site_guid = {$site_guid} "; - } - if ($entity_subtype > 0) { - $query .= " and e.subtype = {$entity_subtype} "; - } - if ($entity_type != "") { - $query .= " and e.type = '{$entity_type}' "; - } - if (is_array($owner_guid)) { - $query .= " and e.container_guid in (".implode(",",$owner_guid).")"; - } else if (is_int($owner_guid)) { - $query .= " and e.container_guid = {$owner_guid} "; - } - if ($start_ts) { - $start_ts = (int)$start_ts; - $query .= " and e.time_created>=$start_ts"; - } - - if ($end_ts) { - $end_ts = (int)$end_ts; - $query .= " and e.time_created<=$end_ts"; - } - - //$userid = get_loggedin_userid(); - //$query .= " and (e.access_id in {$access} or (e.access_id = " . ACCESS_PRIVATE . " and e.owner_guid = {$userid}))"; - $query .= ' and ' . get_access_sql_suffix("e"); // Add access controls - - $query .= " group by msvalue.string having total > {$threshold} order by total desc limit {$limit} "; - - return get_data($query); - - } - - /** - * Loads and displays a tagcloud given particular criteria. - * - * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances) - * @param int $limit Number of tags to return - * @param string $metadata_name Optionally, the name of the field you want to grab for - * @param string $entity_type Optionally, the entity type ('object' etc) - * @param string $entity_subtype The entity subtype, optionally - * @param int $owner_guid The GUID of the tags owner, optionally - * @param int $site_guid Optionally, the site to restrict to (default is the current site) - * @return string THe HTML (or other, depending on view type) of the tagcloud. - */ - - function display_tagcloud($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1) { - - return elgg_view("output/tagcloud",array('value' => get_tags($threshold, $limit, $metadata_name, $entity_type, $entity_subtype, $owner_guid, $site_guid),'object' => $entity_type, 'subtype' => $entity_subtype)); - - } - -?> \ No newline at end of file + } + + if ($site_guid < 0) { + $site_guid = $CONFIG->site_id; + } + + //$access = get_access_list(); + + $query = "SELECT msvalue.string as tag, count(msvalue.id) as total "; + $query .= "FROM {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}metadata md on md.entity_guid = e.guid "; + if ($entity_subtype > 0) { + $query .= " join {$CONFIG->dbprefix}entity_subtypes subtype on subtype.id = e.subtype "; + } + $query .= " join {$CONFIG->dbprefix}metastrings msvalue on msvalue.id = md.value_id "; + + $query .= " where msvalue.string != '' "; + + if ($metadata_name > 0) { + $query .= " and md.name_id = {$metadata_name} "; + } + if ($site_guid > 0) { + $query .= " and e.site_guid = {$site_guid} "; + } + if ($entity_subtype > 0) { + $query .= " and e.subtype = {$entity_subtype} "; + } + if ($entity_type != "") { + $query .= " and e.type = '{$entity_type}' "; + } + if (is_array($owner_guid)) { + $query .= " and e.container_guid in (".implode(",",$owner_guid).")"; + } else if (is_int($owner_guid)) { + $query .= " and e.container_guid = {$owner_guid} "; + } + if ($start_ts) { + $start_ts = (int)$start_ts; + $query .= " and e.time_created>=$start_ts"; + } + + if ($end_ts) { + $end_ts = (int)$end_ts; + $query .= " and e.time_created<=$end_ts"; + } + + //$userid = get_loggedin_userid(); + //$query .= " and (e.access_id in {$access} or (e.access_id = " . ACCESS_PRIVATE . " and e.owner_guid = {$userid}))"; + $query .= ' and ' . get_access_sql_suffix("e"); // Add access controls + + $query .= " group by msvalue.string having total > {$threshold} order by total desc limit {$limit} "; + + return get_data($query); +} + +/** + * Loads and displays a tagcloud given particular criteria. + * + * @param int $threshold Get the threshold of minimum number of each tags to bother with (ie only show tags where there are more than $threshold occurances) + * @param int $limit Number of tags to return + * @param string $metadata_name Optionally, the name of the field you want to grab for + * @param string $entity_type Optionally, the entity type ('object' etc) + * @param string $entity_subtype The entity subtype, optionally + * @param int $owner_guid The GUID of the tags owner, optionally + * @param int $site_guid Optionally, the site to restrict to (default is the current site) + * @return string THe HTML (or other, depending on view type) of the tagcloud. + */ + +function display_tagcloud($threshold = 1, $limit = 10, $metadata_name = "", $entity_type = "object", $entity_subtype = "", $owner_guid = "", $site_guid = -1) { + return elgg_view("output/tagcloud",array('value' => get_tags($threshold, $limit, $metadata_name, $entity_type, $entity_subtype, $owner_guid, $site_guid),'object' => $entity_type, 'subtype' => $entity_subtype)); +} \ No newline at end of file diff --git a/engine/lib/users.php b/engine/lib/users.php index 6aecdc669..7d1fa3d58 100644 --- a/engine/lib/users.php +++ b/engine/lib/users.php @@ -1,1540 +1,1533 @@ attributes['type'] = "user"; + $this->attributes['name'] = ""; + $this->attributes['username'] = ""; + $this->attributes['password'] = ""; + $this->attributes['salt'] = ""; + $this->attributes['email'] = ""; + $this->attributes['language'] = ""; + $this->attributes['code'] = ""; + $this->attributes['banned'] = "no"; + $this->attributes['tables_split'] = 2; + } /** - * ElggUser - * - * Representation of a "user" in the system. + * Construct a new user entity, optionally from a given id value. * - * @package Elgg - * @subpackage Core + * @param mixed $guid If an int, load that GUID. + * If a db row then will attempt to load the rest of the data. + * @throws Exception if there was a problem creating the user. */ - class ElggUser extends ElggEntity - implements Friendable - { - /** - * Initialise the attributes array. - * This is vital to distinguish between metadata and base parameters. - * - * Place your base parameters here. - */ - protected function initialise_attributes() - { - parent::initialise_attributes(); - - $this->attributes['type'] = "user"; - $this->attributes['name'] = ""; - $this->attributes['username'] = ""; - $this->attributes['password'] = ""; - $this->attributes['salt'] = ""; - $this->attributes['email'] = ""; - $this->attributes['language'] = ""; - $this->attributes['code'] = ""; - $this->attributes['banned'] = "no"; - $this->attributes['tables_split'] = 2; - } - - /** - * Construct a new user entity, optionally from a given id value. - * - * @param mixed $guid If an int, load that GUID. - * If a db row then will attempt to load the rest of the data. - * @throws Exception if there was a problem creating the user. - */ - function __construct($guid = null) - { - $this->initialise_attributes(); - - if (!empty($guid)) - { - // Is $guid is a DB row - either a entity row, or a user table row. - if ($guid instanceof stdClass) { - // Load the rest - if (!$this->load($guid->guid)) - throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid)); + function __construct($guid = null) { + $this->initialise_attributes(); + + if (!empty($guid)) { + // Is $guid is a DB row - either a entity row, or a user table row. + if ($guid instanceof stdClass) { + // Load the rest + if (!$this->load($guid->guid)) { + throw new IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid->guid)); } + } - // See if this is a username - else if (is_string($guid)) - { - $guid = get_user_by_username($guid); - foreach ($guid->attributes as $key => $value) - $this->attributes[$key] = $value; - + // See if this is a username + else if (is_string($guid)) { + $guid = get_user_by_username($guid); + foreach ($guid->attributes as $key => $value) { + $this->attributes[$key] = $value; } + } - // Is $guid is an ElggUser? Use a copy constructor - else if ($guid instanceof ElggUser) - { - foreach ($guid->attributes as $key => $value) - $this->attributes[$key] = $value; + // Is $guid is an ElggUser? Use a copy constructor + else if ($guid instanceof ElggUser) { + foreach ($guid->attributes as $key => $value) { + $this->attributes[$key] = $value; } + } - // Is this is an ElggEntity but not an ElggUser = ERROR! - else if ($guid instanceof ElggEntity) - throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggUser')); + // Is this is an ElggEntity but not an ElggUser = ERROR! + else if ($guid instanceof ElggEntity) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggUser')); + } - // We assume if we have got this far, $guid is an int - else if (is_numeric($guid)) { - if (!$this->load($guid)) IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid)); + // We assume if we have got this far, $guid is an int + else if (is_numeric($guid)) { + if (!$this->load($guid)) { + IOException(sprintf(elgg_echo('IOException:FailedToLoadGUID'), get_class(), $guid)); } - - else - throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue')); } - } - /** - * Override the load function. - * This function will ensure that all data is loaded (were possible), so - * if only part of the ElggUser is loaded, it'll load the rest. - * - * @param int $guid - * @return true|false - */ - protected function load($guid) - { - // Test to see if we have the generic stuff - if (!parent::load($guid)) - return false; - - // Check the type - if ($this->attributes['type']!='user') - throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class())); - - // Load missing data - $row = get_user_entity_as_row($guid); - if (($row) && (!$this->isFullyLoaded())) $this->attributes['tables_loaded'] ++; // If $row isn't a cached copy then increment the counter - - // Now put these into the attributes array as core values - $objarray = (array) $row; - foreach($objarray as $key => $value) - $this->attributes[$key] = $value; - - return true; - } - - /** - * Saves this user to the database. - * @return true|false - */ - public function save() - { - // Save generic stuff - if (!parent::save()) - return false; - - // Now save specific stuff - return create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'), $this->get('password'), $this->get('salt'), $this->get('email'), $this->get('language'), $this->get('code')); - } - - /** - * User specific override of the entity delete method. - * - * @return bool - */ - public function delete() - { - // Delete owned data - clear_annotations_by_owner($this->guid); - clear_metadata_by_owner($this->guid); - - // Delete entity - return parent::delete(); - } - - /** - * Ban this user. - * - * @param string $reason Optional reason - */ - public function ban($reason = "") { return ban_user($this->guid, $reason); } - - /** - * Unban this user. - */ - public function unban() { return unban_user($this->guid); } - - /** - * Is this user banned or not? - * - * @return bool - */ - public function isBanned() { return $this->banned == 'yes'; } - - /** - * Get sites that this user is a member of - * - * @param string $subtype Optionally, the subtype of result we want to limit to - * @param int $limit The number of results to return - * @param int $offset Any indexing offset - */ - function getSites($subtype="", $limit = 10, $offset = 0) { - // return get_site_users($this->getGUID(), $subtype, $limit, $offset); - return get_user_sites($this->getGUID(), $subtype, $limit, $offset); - } - - /** - * Add this user to a particular site - * - * @param int $site_guid The guid of the site to add it to - * @return true|false - */ - function addToSite($site_guid) { - // return add_site_user($this->getGUID(), $site_guid); - return add_site_user($site_guid, $this->getGUID()); - } - - /** - * Remove this user from a particular site - * - * @param int $site_guid The guid of the site to remove it from - * @return true|false - */ - function removeFromSite($site_guid) { - //return remove_site_user($this->getGUID(), $site_guid); - return remove_site_user($site_guid, $this->getGUID()); - } - - /** - * Adds a user to this user's friends list - * - * @param int $friend_guid The GUID of the user to add - * @return true|false Depending on success - */ - function addFriend($friend_guid) { return user_add_friend($this->getGUID(), $friend_guid); } - - /** - * Removes a user from this user's friends list - * - * @param int $friend_guid The GUID of the user to remove - * @return true|false Depending on success - */ - function removeFriend($friend_guid) { return user_remove_friend($this->getGUID(), $friend_guid); } - - /** - * Determines whether or not this user is a friend of the currently logged in user - * - * @return true|false - */ - function isFriend() { return user_is_friend(get_loggedin_userid(), $this->getGUID()); } - - /** - * Determines whether this user is friends with another user - * - * @param int $user_guid The GUID of the user to check is on this user's friends list - * @return true|false - */ - function isFriendsWith($user_guid) { return user_is_friend($this->getGUID(), $user_guid); } - - /** - * Determines whether or not this user is on another user's friends list - * - * @param int $user_guid The GUID of the user to check against - * @return true|false - */ - function isFriendOf($user_guid) { return user_is_friend($user_guid, $this->getGUID()); } - - /** - * Retrieves a list of this user's friends - * - * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all) - * @param int $limit The number of users to retrieve - * @param int $offset Indexing offset, if any - * @return array|false Array of ElggUsers, or false, depending on success - */ - function getFriends($subtype = "", $limit = 10, $offset = 0) { return get_user_friends($this->getGUID(), $subtype, $limit, $offset); } - - /** - * Retrieves a list of people who have made this user a friend - * - * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all) - * @param int $limit The number of users to retrieve - * @param int $offset Indexing offset, if any - * @return array|false Array of ElggUsers, or false, depending on success - */ - function getFriendsOf($subtype = "", $limit = 10, $offset = 0) { return get_user_friends_of($this->getGUID(), $subtype, $limit, $offset); } - - /** - * Get an array of ElggObjects owned by this user. - * - * @param string $subtype The subtype of the objects, if any - * @param int $limit Number of results to return - * @param int $offset Any indexing offset - */ - public function getObjects($subtype="", $limit = 10, $offset = 0) { return get_user_objects($this->getGUID(), $subtype, $limit, $offset); } - - /** - * Get an array of ElggObjects owned by this user's friends. - * - * @param string $subtype The subtype of the objects, if any - * @param int $limit Number of results to return - * @param int $offset Any indexing offset - */ - public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) { return get_user_friends_objects($this->getGUID(), $subtype, $limit, $offset); } - - /** - * Counts the number of ElggObjects owned by this user - * - * @param string $subtype The subtypes of the objects, if any - * @return int The number of ElggObjects - */ - public function countObjects($subtype = "") { - return count_user_objects($this->getGUID(), $subtype); - } - - /** - * Get the collections associated with a user. - * - * @param string $subtype Optionally, the subtype of result we want to limit to - * @param int $limit The number of results to return - * @param int $offset Any indexing offset - * @return unknown - */ - public function getCollections($subtype="", $limit = 10, $offset = 0) { return get_user_collections($this->getGUID(), $subtype, $limit, $offset); } - - /** - * If a user's owner is blank, return its own GUID as the owner - * - * @return int User GUID - */ - function getOwner() { - if ($this->owner_guid == 0) - return $this->getGUID(); - - return $this->owner_guid; - } - - // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// - - /** - * Return an array of fields which can be exported. - */ - public function getExportableValues() - { - return array_merge(parent::getExportableValues(), array( - 'name', - 'username', - 'language', - )); + else { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:UnrecognisedValue')); + } } } /** - * Return the user specific details of a user by a row. + * Override the load function. + * This function will ensure that all data is loaded (were possible), so + * if only part of the ElggUser is loaded, it'll load the rest. * * @param int $guid + * @return true|false */ - function get_user_entity_as_row($guid) - { - global $CONFIG; - - /*$row = retrieve_cached_entity_row($guid); - if ($row) - { - // We have already cached this object, so retrieve its value from the cache - if (isset($CONFIG->debug) && $CONFIG->debug == true) - error_log("** Retrieving sub part of GUID:$guid from cache"); - - return $row; + protected function load($guid) { + // Test to see if we have the generic stuff + if (!parent::load($guid)) { + return false; } - else - {*/ - // Object not cached, load it. - if (isset($CONFIG->debug) && $CONFIG->debug == true) - error_log("** Sub part of GUID:$guid loaded from DB"); - - $guid = (int)$guid; - return get_data_row("SELECT * from {$CONFIG->dbprefix}users_entity where guid=$guid"); - //} - } + // Check the type + if ($this->attributes['type']!='user') { + throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, get_class())); + } - /** - * Create or update the extras table for a given user. - * Call create_entity first. - * - * @param int $guid - * @param string $name - * @param string $description - * @param string $url - */ - function create_user_entity($guid, $name, $username, $password, $salt, $email, $language, $code) - { - global $CONFIG; - - $guid = (int)$guid; - $name = sanitise_string($name); - $username = sanitise_string($username); - $password = sanitise_string($password); - $salt = sanitise_string($salt); - $email = sanitise_string($email); - $language = sanitise_string($language); - $code = sanitise_string($code); - - $row = get_entity_as_row($guid); - if ($row) - { - // Exists and you have access to it - - if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}users_entity where guid = {$guid}")) { - $result = update_data("UPDATE {$CONFIG->dbprefix}users_entity set name='$name', username='$username', password='$password', salt='$salt', email='$email', language='$language', code='$code', last_action = ". time() ." where guid = {$guid}"); - if ($result != false) - { - // Update succeeded, continue - $entity = get_entity($guid); - if (trigger_elgg_event('update',$entity->type,$entity)) { - return $guid; - } else { - $entity->delete(); - } - } - } - else - { - // Update failed, attempt an insert. - $result = insert_data("INSERT into {$CONFIG->dbprefix}users_entity (guid, name, username, password, salt, email, language, code) values ($guid, '$name', '$username', '$password', '$salt', '$email', '$language', '$code')"); - if ($result!==false) { - $entity = get_entity($guid); - if (trigger_elgg_event('create',$entity->type,$entity)) { - return $guid; - } else { - $entity->delete(); //delete_entity($guid); - } - } - } + // Load missing data + $row = get_user_entity_as_row($guid); + if (($row) && (!$this->isFullyLoaded())) { + // If $row isn't a cached copy then increment the counter + $this->attributes['tables_loaded'] ++; + } + // Now put these into the attributes array as core values + $objarray = (array) $row; + foreach($objarray as $key => $value) { + $this->attributes[$key] = $value; } - return false; + return true; } /** - * Disables all of a user's entities - * - * @param int $owner_guid The owner GUID - * @return true|false Depending on success + * Saves this user to the database. + * @return true|false */ - function disable_user_entities($owner_guid) { - - global $CONFIG; - $owner_guid = (int) $owner_guid; - if ($entity = get_entity($owner_guid)) { - if (trigger_elgg_event('disable',$entity->type,$entity)) { - if ($entity->canEdit()) { - $res = update_data("UPDATE {$CONFIG->dbprefix}entities set enabled='no' where owner_guid={$owner_guid} or container_guid = {$owner_guid}"); - return $res; - } - } + public function save() { + // Save generic stuff + if (!parent::save()) { + return false; } - return false; + // Now save specific stuff + return create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'), $this->get('password'), $this->get('salt'), $this->get('email'), $this->get('language'), $this->get('code')); } /** - * Ban a user + * User specific override of the entity delete method. * - * @param int $user_guid The user guid - * @param string $reason A reason + * @return bool */ - function ban_user($user_guid, $reason = "") - { - global $CONFIG; - - $user_guid = (int)$user_guid; - $reason = sanitise_string($reason); - - $user = get_entity($user_guid); - - if (($user) && ($user->canEdit()) && ($user instanceof ElggUser)) - { - if (trigger_elgg_event('ban', 'user', $user)) { - // Add reason - if ($reason) - create_metadata($user_guid, 'ban_reason', $reason,'', 0, ACCESS_PUBLIC); - - // Set ban flag - return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='yes' where guid=$user_guid"); - } - } + public function delete() { + // Delete owned data + clear_annotations_by_owner($this->guid); + clear_metadata_by_owner($this->guid); - return false; + // Delete entity + return parent::delete(); } /** - * Unban a user. + * Ban this user. * - * @param int $user_guid Unban a user. + * @param string $reason Optional reason */ - function unban_user($user_guid) - { - global $CONFIG; - - $user_guid = (int)$user_guid; - - $user = get_entity($user_guid); - - if (($user) && ($user->canEdit()) && ($user instanceof ElggUser)) - { - if (trigger_elgg_event('unban', 'user', $user)) { - create_metadata($user_guid, 'ban_reason', '','', 0, ACCESS_PUBLIC); - return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='no' where guid=$user_guid"); - } - } - - return false; + public function ban($reason = "") { + return ban_user($this->guid, $reason); } /** - * THIS FUNCTION IS DEPRECATED. - * - * Delete a user's extra data. - * - * @param int $guid + * Unban this user. */ - function delete_user_entity($guid) - { - system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity')); - - return 1; // Always return that we have deleted one row in order to not break existing code. + public function unban() { + return unban_user($this->guid); } /** - * Get the sites this user is part of + * Is this user banned or not? * - * @param int $user_guid The user's GUID - * @param int $limit Number of results to return - * @param int $offset Any indexing offset - * @return false|array On success, an array of ElggSites + * @return bool */ - function get_user_sites($user_guid, $limit = 10, $offset = 0) { - $user_guid = (int)$user_guid; - $limit = (int)$limit; - $offset = (int)$offset; - - return get_entities_from_relationship("member_of_site", $user_guid, false, "site", "", 0, "time_created desc", $limit, $offset); + public function isBanned() { + return $this->banned == 'yes'; } /** - * Adds a user to another user's friends list. + * Get sites that this user is a member of * - * @param int $user_guid The GUID of the friending user - * @param int $friend_guid The GUID of the user to friend - * @return true|false Depending on success + * @param string $subtype Optionally, the subtype of result we want to limit to + * @param int $limit The number of results to return + * @param int $offset Any indexing offset */ - function user_add_friend($user_guid, $friend_guid) { - $user_guid = (int) $user_guid; - $friend_guid = (int) $friend_guid; - if ($user_guid == $friend_guid) return false; - if (!$friend = get_entity($friend_guid)) return false; - if (!$user = get_entity($user_guid)) return false; - if ( (!($user instanceof ElggUser)) || (!($friend instanceof ElggUser)) ) return false; - return add_entity_relationship($user_guid, "friend", $friend_guid); + function getSites($subtype="", $limit = 10, $offset = 0) { + // return get_site_users($this->getGUID(), $subtype, $limit, $offset); + return get_user_sites($this->getGUID(), $subtype, $limit, $offset); } /** - * Removes a user from another user's friends list. + * Add this user to a particular site * - * @param int $user_guid The GUID of the friending user - * @param int $friend_guid The GUID of the user on the friends list - * @return true|false Depending on success + * @param int $site_guid The guid of the site to add it to + * @return true|false */ - function user_remove_friend($user_guid, $friend_guid) { - global $CONFIG; - - $user_guid = (int) $user_guid; - $friend_guid = (int) $friend_guid; - - // perform cleanup for access lists. - $collections = get_user_access_collections($user_guid); - foreach ($collections as $collection) { - remove_user_from_access_collection($friend_guid, $collection->id); - } - - return remove_entity_relationship($user_guid, "friend", $friend_guid); + function addToSite($site_guid) { + // return add_site_user($this->getGUID(), $site_guid); + return add_site_user($site_guid, $this->getGUID()); } /** - * Determines whether or not a user is another user's friend. + * Remove this user from a particular site * - * @param int $user_guid The GUID of the user - * @param int $friend_guid The GUID of the friend + * @param int $site_guid The guid of the site to remove it from * @return true|false */ - function user_is_friend($user_guid, $friend_guid) { - return check_entity_relationship($user_guid, "friend", $friend_guid); + function removeFromSite($site_guid) { + //return remove_site_user($this->getGUID(), $site_guid); + return remove_site_user($site_guid, $this->getGUID()); } /** - * Obtains a given user's friends + * Adds a user to this user's friends list * - * @param int $user_guid The user's GUID - * @param string $subtype The subtype of users, if any - * @param int $limit Number of results to return (default 10) - * @param int $offset Indexing offset, if any - * @return false|array Either an array of ElggUsers or false, depending on success + * @param int $friend_guid The GUID of the user to add + * @return true|false Depending on success */ - function get_user_friends($user_guid, $subtype = "", $limit = 10, $offset = 0) { - return get_entities_from_relationship("friend",$user_guid,false,"user",$subtype,0,"time_created desc",$limit,$offset); + function addFriend($friend_guid) { + return user_add_friend($this->getGUID(), $friend_guid); } /** - * Obtains the people who have made a given user a friend + * Removes a user from this user's friends list * - * @param int $user_guid The user's GUID - * @param string $subtype The subtype of users, if any - * @param int $limit Number of results to return (default 10) - * @param int $offset Indexing offset, if any - * @return false|array Either an array of ElggUsers or false, depending on success + * @param int $friend_guid The GUID of the user to remove + * @return true|false Depending on success */ - function get_user_friends_of($user_guid, $subtype = "", $limit = 10, $offset = 0) { - return get_entities_from_relationship("friend",$user_guid,true,"user",$subtype,0,"time_created desc",$limit,$offset); + function removeFriend($friend_guid) { + return user_remove_friend($this->getGUID(), $friend_guid); } /** - * Obtains a list of objects owned by a user + * Determines whether or not this user is a friend of the currently logged in user * - * @param int $user_guid The GUID of the owning user - * @param string $subtype Optionally, the subtype of objects - * @param int $limit The number of results to return (default 10) - * @param int $offset Indexing offset, if any - * @param int $timelower The earliest time the entity can have been created. Default: all - * @param int $timeupper The latest time the entity can have been created. Default: all - * @return false|array An array of ElggObjects or false, depending on success + * @return true|false */ - function get_user_objects($user_guid, $subtype = "", $limit = 10, $offset = 0, $timelower = 0, $timeupper = 0) { - $ntt = get_entities('object',$subtype, $user_guid, "time_created desc", $limit, $offset,false,0,$user_guid,$timelower, $timeupper); - return $ntt; + function isFriend() { + return user_is_friend(get_loggedin_userid(), $this->getGUID()); } /** - * Counts the objects (optionally of a particular subtype) owned by a user + * Determines whether this user is friends with another user * - * @param int $user_guid The GUID of the owning user - * @param string $subtype Optionally, the subtype of objects - * @param int $timelower The earliest time the entity can have been created. Default: all - * @param int $timeupper The latest time the entity can have been created. Default: all - * @return int The number of objects the user owns (of this subtype) + * @param int $user_guid The GUID of the user to check is on this user's friends list + * @return true|false */ - function count_user_objects($user_guid, $subtype = "", $timelower, $timeupper) { - $total = get_entities('object', $subtype, $user_guid, "time_created desc", null, null, true, 0, $user_guid,$timelower,$timeupper); - return $total; + function isFriendsWith($user_guid) { + return user_is_friend($this->getGUID(), $user_guid); } /** - * Displays a list of user objects of a particular subtype, with navigation. - * - * @see elgg_view_entity_list + * Determines whether or not this user is on another user's friends list * - * @param int $user_guid The GUID of the user - * @param string $subtype The object subtype - * @param int $limit The number of entities to display on a page - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param int $timelower The earliest time the entity can have been created. Default: all - * @param int $timeupper The latest time the entity can have been created. Default: all - * @return string The list in a form suitable to display + * @param int $user_guid The GUID of the user to check against + * @return true|false */ - function list_user_objects($user_guid, $subtype = "", $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true, $timelower = 0, $timeupper = 0) { - - $offset = (int) get_input('offset'); - $limit = (int) $limit; - $count = (int) count_user_objects($user_guid, $subtype,$timelower,$timeupper); - $entities = get_user_objects($user_guid, $subtype, $limit, $offset, $timelower, $timeupper); - - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); - + function isFriendOf($user_guid) { + return user_is_friend($user_guid, $this->getGUID()); } /** - * Obtains a list of objects owned by a user's friends + * Retrieves a list of this user's friends * - * @param int $user_guid The GUID of the user to get the friends of - * @param string $subtype Optionally, the subtype of objects - * @param int $limit The number of results to return (default 10) + * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all) + * @param int $limit The number of users to retrieve * @param int $offset Indexing offset, if any - * @return false|array An array of ElggObjects or false, depending on success + * @return array|false Array of ElggUsers, or false, depending on success */ - function get_user_friends_objects($user_guid, $subtype = "", $limit = 10, $offset = 0) { - if ($friends = get_user_friends($user_guid, $subtype, 999999, 0)) { - $friendguids = array(); - foreach($friends as $friend) { - $friendguids[] = $friend->getGUID(); - } - return get_entities('object',$subtype,$friendguids, "time_created desc", $limit, $offset, false, 0, $friendguids); - } - return false; + function getFriends($subtype = "", $limit = 10, $offset = 0) { + return get_user_friends($this->getGUID(), $subtype, $limit, $offset); } /** - * Counts the number of objects owned by a user's friends + * Retrieves a list of people who have made this user a friend * - * @param int $user_guid The GUID of the user to get the friends of - * @param string $subtype Optionally, the subtype of objects - * @return int The number of objects + * @param string $subtype Optionally, the subtype of user to filter to (leave blank for all) + * @param int $limit The number of users to retrieve + * @param int $offset Indexing offset, if any + * @return array|false Array of ElggUsers, or false, depending on success */ - function count_user_friends_objects($user_guid, $subtype = "") { - if ($friends = get_user_friends($user_guid, $subtype, 999999, 0)) { - $friendguids = array(); - foreach($friends as $friend) { - $friendguids[] = $friend->getGUID(); - } - return get_entities('object',$subtype,$friendguids, "time_created desc", $limit, $offset, true, 0, $friendguids); - } - return 0; + function getFriendsOf($subtype = "", $limit = 10, $offset = 0) { + return get_user_friends_of($this->getGUID(), $subtype, $limit, $offset); } /** - * Displays a list of a user's friends' objects of a particular subtype, with navigation. + * Get an array of ElggObjects owned by this user. * - * @see elgg_view_entity_list - * - * @param int $user_guid The GUID of the user - * @param string $subtype The object subtype - * @param int $limit The number of entities to display on a page - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow you to flip to gallery mode (default: true) - * @return string The list in a form suitable to display + * @param string $subtype The subtype of the objects, if any + * @param int $limit Number of results to return + * @param int $offset Any indexing offset */ - function list_user_friends_objects($user_guid, $subtype = "", $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) { - - $offset = (int) get_input('offset'); - $limit = (int) $limit; - $count = (int) count_user_friends_objects($user_guid, $subtype); - $entities = get_user_friends_objects($user_guid, $subtype, $limit, $offset); - - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); - + public function getObjects($subtype="", $limit = 10, $offset = 0) { + return get_user_objects($this->getGUID(), $subtype, $limit, $offset); } /** - * Get user objects by an array of metadata + * Get an array of ElggObjects owned by this user's friends. * - * @param int $user_guid The GUID of the owning user - * @param string $subtype Optionally, the subtype of objects - * @paran array $metadata An array of metadata - * @param int $limit The number of results to return (default 10) - * @param int $offset Indexing offset, if any - * @return false|array An array of ElggObjects or false, depending on success - * @return unknown + * @param string $subtype The subtype of the objects, if any + * @param int $limit Number of results to return + * @param int $offset Any indexing offset */ - function get_user_objects_by_metadata($user_guid, $subtype = "", $metadata = array(), $limit = 0, $offset = 0) { - - return get_entities_from_metadata_multi($metadata,"object",$subtype,$user_guid,$limit,$offset); - + public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) { + return get_user_friends_objects($this->getGUID(), $subtype, $limit, $offset); } /** - * Get a user object from a GUID. + * Counts the number of ElggObjects owned by this user * - * This function returns an ElggUser from a given GUID. - * @param int $guid The GUID - * @return ElggUser|false + * @param string $subtype The subtypes of the objects, if any + * @return int The number of ElggObjects */ - function get_user($guid) - { - if (!empty($guid)) // Fixes "Exception thrown without stack frame" when db_select fails - $result = get_entity($guid); - - if ((!empty($result)) && (!($result instanceof ElggUser))) - //throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, 'ElggUser')); - return false; - - if (!empty($result)) - return $result; - - return false; + public function countObjects($subtype = "") { + return count_user_objects($this->getGUID(), $subtype); } /** - * Get user by username + * Get the collections associated with a user. * - * @param string $username The user's username - * @return ElggUser|false Depending on success + * @param string $subtype Optionally, the subtype of result we want to limit to + * @param int $limit The number of results to return + * @param int $offset Any indexing offset + * @return unknown */ - function get_user_by_username($username) - { - global $CONFIG, $USERNAME_TO_GUID_MAP_CACHE; - - $username = sanitise_string($username); - $access = get_access_sql_suffix('e'); - - // Caching - if ( (isset($USERNAME_TO_GUID_MAP_CACHE[$username])) && (retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username])) ) - return retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]); - - $row = get_data_row("SELECT e.* from {$CONFIG->dbprefix}users_entity u join {$CONFIG->dbprefix}entities e on e.guid=u.guid where u.username='$username' and $access "); - if ($row) { - $USERNAME_TO_GUID_MAP_CACHE[$username] = $row->guid; - return new ElggUser($row); - } - - return false; + public function getCollections($subtype="", $limit = 10, $offset = 0) { + return get_user_collections($this->getGUID(), $subtype, $limit, $offset); } /** - * Get user by session code + * If a user's owner is blank, return its own GUID as the owner * - * @param string $code The session code - * @return ElggUser|false Depending on success + * @return int User GUID */ - function get_user_by_code($code) - { - global $CONFIG, $CODE_TO_GUID_MAP_CACHE; - - $code = sanitise_string($code); - - $access = get_access_sql_suffix('e'); - - // Caching - if ( (isset($CODE_TO_GUID_MAP_CACHE[$code])) && (retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code])) ) - return retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]); - - $row = get_data_row("SELECT e.* from {$CONFIG->dbprefix}users_entity u join {$CONFIG->dbprefix}entities e on e.guid=u.guid where u.code='$code' and $access"); - if ($row) { - $CODE_TO_GUID_MAP_CACHE[$code] = $row->guid; - return new ElggUser($row); + function getOwner() { + if ($this->owner_guid == 0) { + return $this->getGUID(); } - return false; + return $this->owner_guid; } - /** - * Get an array of users from their - * - * @param string $email Email address. - * @return Array of users - */ - function get_user_by_email($email) - { - global $CONFIG; - - $email = sanitise_string($email); - - $access = get_access_sql_suffix('e'); - - $query = "SELECT e.* from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where email='$email' and $access"; - - return get_data($query, 'entity_row_to_elggstar'); - } + // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// /** - * 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 an array of fields which can be exported. */ - function search_for_user($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) + public function getExportableValues() { + return array_merge(parent::getExportableValues(), array( + 'name', + 'username', + 'language', + )); + } +} + +/** + * Return the user specific details of a user by a row. + * + * @param int $guid + */ +function get_user_entity_as_row($guid) { + global $CONFIG; + + /*$row = retrieve_cached_entity_row($guid); + if ($row) { - global $CONFIG; + // We have already cached this object, so retrieve its value from the cache + if (isset($CONFIG->debug) && $CONFIG->debug == true) + error_log("** Retrieving sub part of GUID:$guid from cache"); - $criteria = sanitise_string($criteria); - $limit = (int)$limit; - $offset = (int)$offset; - $order_by = sanitise_string($order_by); - - $access = get_access_sql_suffix("e"); - - if ($order_by == "") $order_by = "e.time_created desc"; + return $row; + } + else + {*/ + // Object not cached, load it. + if (isset($CONFIG->debug) && $CONFIG->debug == true) { + error_log("** Sub part of GUID:$guid loaded from DB"); + } - if ($count) { - $query = "SELECT count(e.guid) as total "; - } else { - $query = "SELECT e.* "; - } - $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where "; - // $query .= " match(u.name,u.username) against ('$criteria') "; - $query .= "(u.name like \"%{$criteria}%\" or u.username like \"%{$criteria}%\")"; - $query .= " and $access"; - - if (!$count) { - $query .= " order by $order_by limit $offset, $limit"; // Add order and limit - return get_data($query, "entity_row_to_elggstar"); + $guid = (int)$guid; + + return get_data_row("SELECT * from {$CONFIG->dbprefix}users_entity where guid=$guid"); + //} +} + +/** + * Create or update the extras table for a given user. + * Call create_entity first. + * + * @param int $guid + * @param string $name + * @param string $description + * @param string $url + */ +function create_user_entity($guid, $name, $username, $password, $salt, $email, $language, $code) { + global $CONFIG; + + $guid = (int)$guid; + $name = sanitise_string($name); + $username = sanitise_string($username); + $password = sanitise_string($password); + $salt = sanitise_string($salt); + $email = sanitise_string($email); + $language = sanitise_string($language); + $code = sanitise_string($code); + + $row = get_entity_as_row($guid); + if ($row) { + // Exists and you have access to it + + if ($exists = get_data_row("SELECT guid from {$CONFIG->dbprefix}users_entity where guid = {$guid}")) { + $result = update_data("UPDATE {$CONFIG->dbprefix}users_entity set name='$name', username='$username', password='$password', salt='$salt', email='$email', language='$language', code='$code', last_action = ". time() ." where guid = {$guid}"); + if ($result != false) { + // Update succeeded, continue + $entity = get_entity($guid); + if (trigger_elgg_event('update',$entity->type,$entity)) { + return $guid; + } else { + $entity->delete(); + } + } } else { - if ($count = get_data_row($query)) { - return $count->total; + // Update failed, attempt an insert. + $result = insert_data("INSERT into {$CONFIG->dbprefix}users_entity (guid, name, username, password, salt, email, language, code) values ($guid, '$name', '$username', '$password', '$salt', '$email', '$language', '$code')"); + if ($result!==false) { + $entity = get_entity($guid); + if (trigger_elgg_event('create',$entity->type,$entity)) { + return $guid; + } else { + $entity->delete(); //delete_entity($guid); + } } } - return false; } - /** - * Displays a list of user objects that have been searched for. - * - * @see elgg_view_entity_list - * - * @param string $tag Search criteria - * @param int $limit The number of entities to display on a page - * @return string The list in a form suitable to display - */ - function list_user_search($tag, $limit = 10) { - - $offset = (int) get_input('offset'); - $limit = (int) $limit; - $count = (int) search_for_user($tag, 10, 0, '', true); - $entities = search_for_user($tag, $limit, $offset); - - return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, false); - + return false; +} + +/** + * Disables all of a user's entities + * + * @param int $owner_guid The owner GUID + * @return true|false Depending on success + */ +function disable_user_entities($owner_guid) { + global $CONFIG; + $owner_guid = (int) $owner_guid; + if ($entity = get_entity($owner_guid)) { + if (trigger_elgg_event('disable',$entity->type,$entity)) { + if ($entity->canEdit()) { + $res = update_data("UPDATE {$CONFIG->dbprefix}entities set enabled='no' where owner_guid={$owner_guid} or container_guid = {$owner_guid}"); + return $res; + } + } } - /** - * A function that returns a maximum of $limit users who have done something within the last - * $seconds seconds. - * - * @param int $seconds Number of seconds (default 600 = 10min) - * @param int $limit Limit, default 10. - * @param int $offset Offset, defualt 0. - */ - function find_active_users($seconds = 600, $limit = 10, $offset = 0) - { - global $CONFIG; + return false; +} - $seconds = (int)$seconds; - $limit = (int)$limit; - $offset = (int)$offset; +/** + * Ban a user + * + * @param int $user_guid The user guid + * @param string $reason A reason + */ +function ban_user($user_guid, $reason = "") { + global $CONFIG; - $time = time() - $seconds; + $user_guid = (int)$user_guid; + $reason = sanitise_string($reason); - $access = get_access_sql_suffix("e"); + $user = get_entity($user_guid); - $query = "SELECT distinct e.* from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid = u.guid where u.last_action >= {$time} and $access order by u.last_action desc limit {$offset},{$limit}"; + if (($user) && ($user->canEdit()) && ($user instanceof ElggUser)) { + if (trigger_elgg_event('ban', 'user', $user)) { + // Add reason + if ($reason) { + create_metadata($user_guid, 'ban_reason', $reason,'', 0, ACCESS_PUBLIC); + } - return get_data($query, "entity_row_to_elggstar"); + // Set ban flag + return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='yes' where guid=$user_guid"); + } } - /** - * Generate and send a password request email to a given user's registered email address. - * - * @param int $user_guid - */ - function send_new_password_request($user_guid) - { - global $CONFIG; - - $user_guid = (int)$user_guid; + return false; +} - $user = get_entity($user_guid); - if ($user) - { - // generate code - $code = generate_random_cleartext_password(); - //create_metadata($user_guid, 'conf_code', $code,'', 0, ACCESS_PRIVATE); - set_private_setting($user_guid, 'passwd_conf_code', $code); - - // generate link - $link = $CONFIG->site->url . "action/user/passwordreset?u=$user_guid&c=$code"; +/** + * Unban a user. + * + * @param int $user_guid Unban a user. + */ +function unban_user($user_guid) { + global $CONFIG; - // generate email - $email = sprintf(elgg_echo('email:resetreq:body'), $user->name, $_SERVER['REMOTE_ADDR'], $link); + $user_guid = (int)$user_guid; - return notify_user($user->guid, $CONFIG->site->guid, elgg_echo('email:resetreq:subject'), $email, NULL, 'email'); + $user = get_entity($user_guid); + if (($user) && ($user->canEdit()) && ($user instanceof ElggUser)) { + if (trigger_elgg_event('unban', 'user', $user)) { + create_metadata($user_guid, 'ban_reason', '','', 0, ACCESS_PUBLIC); + return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='no' where guid=$user_guid"); } + } + return false; +} + +/** + * THIS FUNCTION IS DEPRECATED. + * + * Delete a user's extra data. + * + * @param int $guid + */ +function delete_user_entity($guid) { + system_message(sprintf(elgg_echo('deprecatedfunction'), 'delete_user_entity')); + + return 1; // Always return that we have deleted one row in order to not break existing code. +} + +/** + * Get the sites this user is part of + * + * @param int $user_guid The user's GUID + * @param int $limit Number of results to return + * @param int $offset Any indexing offset + * @return false|array On success, an array of ElggSites + */ +function get_user_sites($user_guid, $limit = 10, $offset = 0) { + $user_guid = (int)$user_guid; + $limit = (int)$limit; + $offset = (int)$offset; + + return get_entities_from_relationship("member_of_site", $user_guid, false, "site", "", 0, "time_created desc", $limit, $offset); +} + +/** + * Adds a user to another user's friends list. + * + * @param int $user_guid The GUID of the friending user + * @param int $friend_guid The GUID of the user to friend + * @return true|false Depending on success + */ +function user_add_friend($user_guid, $friend_guid) { + $user_guid = (int) $user_guid; + $friend_guid = (int) $friend_guid; + if ($user_guid == $friend_guid) { return false; } - - /** - * Low level function to reset a given user's password. - * - * This can only be called from execute_new_password_request(). - * - * @param int $user_guid The user. - * @param string $password password text (which will then be converted into a hash and stored) - */ - function force_user_password_reset($user_guid, $password) - { - global $CONFIG; - - if (call_gatekeeper('execute_new_password_request', __FILE__)) - { - $user = get_entity($user_guid); - - if ($user) - { - $salt = generate_random_cleartext_password(); // Reset the salt - $user->salt = $salt; - - $hash = generate_user_password($user, $password); - - return update_data("UPDATE {$CONFIG->dbprefix}users_entity set password='$hash', salt='$salt' where guid=$user_guid"); - } - } - + if (!$friend = get_entity($friend_guid)) { return false; } - - /** - * Validate and execute a password reset for a user. - * - * @param int $user_guid The user id - * @param string $conf_code Confirmation code as sent in the request email. - */ - function execute_new_password_request($user_guid, $conf_code) - { - global $CONFIG; - - $user_guid = (int)$user_guid; - - $user = get_entity($user_guid); - if (($user) && (get_private_setting($user_guid, 'passwd_conf_code') == $conf_code)) - { - $password = generate_random_cleartext_password(); - - if (force_user_password_reset($user_guid, $password)) - { - //remove_metadata($user_guid, 'conf_code'); - remove_private_setting($user_guid, 'passwd_conf_code'); - - $email = sprintf(elgg_echo('email:resetpassword:body'), $user->name, $password); - - return notify_user($user->guid, $CONFIG->site->guid, elgg_echo('email:resetpassword:subject'), $email, NULL, 'email'); - } - } - + if (!$user = get_entity($user_guid)) { + return false; + } + if ((!($user instanceof ElggUser)) || (!($friend instanceof ElggUser))) { return false; } + return add_entity_relationship($user_guid, "friend", $friend_guid); +} + +/** + * Removes a user from another user's friends list. + * + * @param int $user_guid The GUID of the friending user + * @param int $friend_guid The GUID of the user on the friends list + * @return true|false Depending on success + */ +function user_remove_friend($user_guid, $friend_guid) { + global $CONFIG; + + $user_guid = (int) $user_guid; + $friend_guid = (int) $friend_guid; + + // perform cleanup for access lists. + $collections = get_user_access_collections($user_guid); + foreach ($collections as $collection) { + remove_user_from_access_collection($friend_guid, $collection->id); + } - /** - * Set the validation status for a user. - * - * @param bool $status Validated (true) or false - * @param string $method Optional method to say how a user was validated - * @return bool - */ - function set_user_validation_status($user_guid, $status, $method = '') - { - if (!$status) $method = ''; - - if ($status) - { - if ( - (create_metadata($user_guid, 'validated', $status,'', 0, ACCESS_PUBLIC)) && - (create_metadata($user_guid, 'validated_method', $method,'', 0, ACCESS_PUBLIC)) - ) - return true; + return remove_entity_relationship($user_guid, "friend", $friend_guid); +} + +/** + * Determines whether or not a user is another user's friend. + * + * @param int $user_guid The GUID of the user + * @param int $friend_guid The GUID of the friend + * @return true|false + */ +function user_is_friend($user_guid, $friend_guid) { + return check_entity_relationship($user_guid, "friend", $friend_guid); +} + +/** + * Obtains a given user's friends + * + * @param int $user_guid The user's GUID + * @param string $subtype The subtype of users, if any + * @param int $limit Number of results to return (default 10) + * @param int $offset Indexing offset, if any + * @return false|array Either an array of ElggUsers or false, depending on success + */ +function get_user_friends($user_guid, $subtype = "", $limit = 10, $offset = 0) { + return get_entities_from_relationship("friend",$user_guid,false,"user",$subtype,0,"time_created desc",$limit,$offset); +} + +/** + * Obtains the people who have made a given user a friend + * + * @param int $user_guid The user's GUID + * @param string $subtype The subtype of users, if any + * @param int $limit Number of results to return (default 10) + * @param int $offset Indexing offset, if any + * @return false|array Either an array of ElggUsers or false, depending on success + */ +function get_user_friends_of($user_guid, $subtype = "", $limit = 10, $offset = 0) { + return get_entities_from_relationship("friend",$user_guid,true,"user",$subtype,0,"time_created desc",$limit,$offset); +} + +/** + * Obtains a list of objects owned by a user + * + * @param int $user_guid The GUID of the owning user + * @param string $subtype Optionally, the subtype of objects + * @param int $limit The number of results to return (default 10) + * @param int $offset Indexing offset, if any + * @param int $timelower The earliest time the entity can have been created. Default: all + * @param int $timeupper The latest time the entity can have been created. Default: all + * @return false|array An array of ElggObjects or false, depending on success + */ +function get_user_objects($user_guid, $subtype = "", $limit = 10, $offset = 0, $timelower = 0, $timeupper = 0) { + $ntt = get_entities('object',$subtype, $user_guid, "time_created desc", $limit, $offset,false,0,$user_guid,$timelower, $timeupper); + return $ntt; +} + +/** + * Counts the objects (optionally of a particular subtype) owned by a user + * + * @param int $user_guid The GUID of the owning user + * @param string $subtype Optionally, the subtype of objects + * @param int $timelower The earliest time the entity can have been created. Default: all + * @param int $timeupper The latest time the entity can have been created. Default: all + * @return int The number of objects the user owns (of this subtype) + */ +function count_user_objects($user_guid, $subtype = "", $timelower, $timeupper) { + $total = get_entities('object', $subtype, $user_guid, "time_created desc", null, null, true, 0, $user_guid,$timelower,$timeupper); + return $total; +} + +/** + * Displays a list of user objects of a particular subtype, with navigation. + * + * @see elgg_view_entity_list + * + * @param int $user_guid The GUID of the user + * @param string $subtype The object subtype + * @param int $limit The number of entities to display on a page + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param int $timelower The earliest time the entity can have been created. Default: all + * @param int $timeupper The latest time the entity can have been created. Default: all + * @return string The list in a form suitable to display + */ +function list_user_objects($user_guid, $subtype = "", $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true, $timelower = 0, $timeupper = 0) { + $offset = (int) get_input('offset'); + $limit = (int) $limit; + $count = (int) count_user_objects($user_guid, $subtype,$timelower,$timeupper); + $entities = get_user_objects($user_guid, $subtype, $limit, $offset, $timelower, $timeupper); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); +} + +/** + * Obtains a list of objects owned by a user's friends + * + * @param int $user_guid The GUID of the user to get the friends of + * @param string $subtype Optionally, the subtype of objects + * @param int $limit The number of results to return (default 10) + * @param int $offset Indexing offset, if any + * @return false|array An array of ElggObjects or false, depending on success + */ +function get_user_friends_objects($user_guid, $subtype = "", $limit = 10, $offset = 0) { + if ($friends = get_user_friends($user_guid, $subtype, 999999, 0)) { + $friendguids = array(); + foreach($friends as $friend) { + $friendguids[] = $friend->getGUID(); } - else - { - $validated = get_metadata_byname($user_guid, 'validated'); - $validated_method = get_metadata_byname($user_guid, 'validated_method'); - - if ( - ($validated) && - ($validated_method) && - (delete_metadata($validated->id)) && - (delete_metadata($validated_method->id)) - ) - return true; + return get_entities('object',$subtype,$friendguids, "time_created desc", $limit, $offset, false, 0, $friendguids); + } + return false; +} + +/** + * Counts the number of objects owned by a user's friends + * + * @param int $user_guid The GUID of the user to get the friends of + * @param string $subtype Optionally, the subtype of objects + * @return int The number of objects + */ +function count_user_friends_objects($user_guid, $subtype = "") { + if ($friends = get_user_friends($user_guid, $subtype, 999999, 0)) { + $friendguids = array(); + foreach($friends as $friend) { + $friendguids[] = $friend->getGUID(); } + return get_entities('object',$subtype,$friendguids, "time_created desc", $limit, $offset, true, 0, $friendguids); + } + return 0; +} + +/** + * Displays a list of a user's friends' objects of a particular subtype, with navigation. + * + * @see elgg_view_entity_list + * + * @param int $user_guid The GUID of the user + * @param string $subtype The object subtype + * @param int $limit The number of entities to display on a page + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow you to flip to gallery mode (default: true) + * @return string The list in a form suitable to display + */ +function list_user_friends_objects($user_guid, $subtype = "", $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) { + $offset = (int) get_input('offset'); + $limit = (int) $limit; + $count = (int) count_user_friends_objects($user_guid, $subtype); + $entities = get_user_friends_objects($user_guid, $subtype, $limit, $offset); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); +} + +/** + * Get user objects by an array of metadata + * + * @param int $user_guid The GUID of the owning user + * @param string $subtype Optionally, the subtype of objects + * @paran array $metadata An array of metadata + * @param int $limit The number of results to return (default 10) + * @param int $offset Indexing offset, if any + * @return false|array An array of ElggObjects or false, depending on success + * @return unknown + */ +function get_user_objects_by_metadata($user_guid, $subtype = "", $metadata = array(), $limit = 0, $offset = 0) { + return get_entities_from_metadata_multi($metadata,"object",$subtype,$user_guid,$limit,$offset); +} + +/** + * Get a user object from a GUID. + * + * This function returns an ElggUser from a given GUID. + * @param int $guid The GUID + * @return ElggUser|false + */ +function get_user($guid) { + // Fixes "Exception thrown without stack frame" when db_select fails + if (!empty($guid)) { + $result = get_entity($guid); + } + if ((!empty($result)) && (!($result instanceof ElggUser))) { + //throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $guid, 'ElggUser')); return false; } - /** - * Trigger an event requesting that a user guid be validated somehow - either by email address or some other way. - * - * This event invalidates any existing values and returns - * - * @param unknown_type $user_guid - */ - function request_user_validation($user_guid) - { - $user = get_entity($user_guid); + if (!empty($result)) { + return $result; + } - if (($user) && ($user instanceof ElggUser)) - { - // invalidate any existing validations - set_user_validation_status($user_guid, false); + return false; +} - // request validation - trigger_elgg_event('validate', 'user', $user); +/** + * Get user by username + * + * @param string $username The user's username + * @return ElggUser|false Depending on success + */ +function get_user_by_username($username) { + global $CONFIG, $USERNAME_TO_GUID_MAP_CACHE; - } + $username = sanitise_string($username); + $access = get_access_sql_suffix('e'); + + // Caching + if ( (isset($USERNAME_TO_GUID_MAP_CACHE[$username])) && (retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username])) ) { + return retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]); } - /** - * Validates an email address. - * - * @param string $address Email address. - * @return bool - */ - function is_email_address($address) - { - // TODO: Make this better! + $row = get_data_row("SELECT e.* from {$CONFIG->dbprefix}users_entity u join {$CONFIG->dbprefix}entities e on e.guid=u.guid where u.username='$username' and $access "); + if ($row) { + $USERNAME_TO_GUID_MAP_CACHE[$username] = $row->guid; + return new ElggUser($row); + } - if (strpos($address, '@')=== false) - return false; + return false; +} - if (strpos($address, '.')=== false) - return false; +/** + * Get user by session code + * + * @param string $code The session code + * @return ElggUser|false Depending on success + */ +function get_user_by_code($code) { + global $CONFIG, $CODE_TO_GUID_MAP_CACHE; - return true; - } + $code = sanitise_string($code); - /** - * Simple function that will generate a random clear text password suitable for feeding into generate_user_password(). - * - * @see generate_user_password - * @return string - */ - function generate_random_cleartext_password() - { - return substr(md5(microtime() . rand()), 0, 8); + $access = get_access_sql_suffix('e'); + + // Caching + if ( (isset($CODE_TO_GUID_MAP_CACHE[$code])) && (retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code])) ) { + return retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]); } - /** - * Generate a password for a user, currently uses MD5. - * - * Later may introduce salting etc. - * - * @param ElggUser $user The user this is being generated for. - * @param string $password Password in clear text - */ - function generate_user_password(ElggUser $user, $password) - { - return md5($password . $user->salt); + $row = get_data_row("SELECT e.* from {$CONFIG->dbprefix}users_entity u join {$CONFIG->dbprefix}entities e on e.guid=u.guid where u.code='$code' and $access"); + if ($row) { + $CODE_TO_GUID_MAP_CACHE[$code] = $row->guid; + return new ElggUser($row); } - /** - * Simple function which ensures that a username contains only valid characters. - * - * This should only permit chars that are valid on the file system as well. - * - * @param string $username - * @throws RegistrationException on invalid - */ - function validate_username($username) - { - global $CONFIG; + return false; +} - // Basic, check length - if (!isset($CONFIG->minusername)) { - $CONFIG->minusername = 4; - } +/** + * Get an array of users from their + * + * @param string $email Email address. + * @return Array of users + */ +function get_user_by_email($email) { + global $CONFIG; - if (strlen($username) < $CONFIG->minusername) - throw new RegistrationException(elgg_echo('registration:usernametooshort')); + $email = sanitise_string($email); - // Blacklist for bad characters (partially nicked from mediawiki) + $access = get_access_sql_suffix('e'); - $blacklist = '/[' . - '\x{0080}-\x{009f}' . # iso-8859-1 control chars - '\x{00a0}' . # non-breaking space - '\x{2000}-\x{200f}' . # various whitespace - '\x{2028}-\x{202f}' . # breaks and control chars - '\x{3000}' . # ideographic space - '\x{e000}-\x{f8ff}' . # private use - ']/u'; + $query = "SELECT e.* from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where email='$email' and $access"; - if ( - preg_match($blacklist, $username) - ) - throw new RegistrationException(elgg_echo('registration:invalidchars')); + return get_data($query, 'entity_row_to_elggstar'); +} - // Belts and braces TODO: Tidy into main unicode - $blacklist2 = '/\\"\'*& ?#%^(){}[]~?<>;|¬`@-+='; - for ($n=0; $n < strlen($blacklist2); $n++) - if (strpos($username, $blacklist2[$n])!==false) - throw new RegistrationException(elgg_echo('registration:invalidchars')); +/** + * 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. + */ +function search_for_user($criteria, $limit = 10, $offset = 0, $order_by = "", $count = false) { + global $CONFIG; - $result = true; - return trigger_plugin_hook('registeruser:validate:username', 'all', array('username' => $username), $result); - } + $criteria = sanitise_string($criteria); + $limit = (int)$limit; + $offset = (int)$offset; + $order_by = sanitise_string($order_by); - /** - * Simple validation of a password. - * - * @param string $password - * @throws RegistrationException on invalid - */ - function validate_password($password) - { - if (strlen($password)<6) throw new RegistrationException(elgg_echo('registration:passwordtooshort')); + $access = get_access_sql_suffix("e"); - $result = true; - return trigger_plugin_hook('registeruser:validate:password', 'all', array('password' => $password), $result); + if ($order_by == "") { + $order_by = "e.time_created desc"; } - /** - * Simple validation of a email. - * - * @param string $address - * @throws RegistrationException on invalid - * @return bool - */ - function validate_email_address($address) - { - if (!is_email_address($address)) throw new RegistrationException(elgg_echo('registration:notemail')); + if ($count) { + $query = "SELECT count(e.guid) as total "; + } else { + $query = "SELECT e.* "; + } + $query .= "from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid=u.guid where "; + // $query .= " match(u.name,u.username) against ('$criteria') "; + $query .= "(u.name like \"%{$criteria}%\" or u.username like \"%{$criteria}%\")"; + $query .= " and $access"; - // Got here, so lets try a hook (defaulting to ok) - $result = true; - return trigger_plugin_hook('registeruser:validate:email', 'all', array('email' => $address), $result); + if (!$count) { + $query .= " order by $order_by limit $offset, $limit"; // Add order and limit + return get_data($query, "entity_row_to_elggstar"); + } else { + if ($count = get_data_row($query)) { + return $count->total; + } + } + return false; +} + +/** + * Displays a list of user objects that have been searched for. + * + * @see elgg_view_entity_list + * + * @param string $tag Search criteria + * @param int $limit The number of entities to display on a page + * @return string The list in a form suitable to display + */ +function list_user_search($tag, $limit = 10) { + $offset = (int) get_input('offset'); + $limit = (int) $limit; + $count = (int) search_for_user($tag, 10, 0, '', true); + $entities = search_for_user($tag, $limit, $offset); + + return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, false); +} + +/** + * A function that returns a maximum of $limit users who have done something within the last + * $seconds seconds. + * + * @param int $seconds Number of seconds (default 600 = 10min) + * @param int $limit Limit, default 10. + * @param int $offset Offset, defualt 0. + */ +function find_active_users($seconds = 600, $limit = 10, $offset = 0) { + global $CONFIG; + + $seconds = (int)$seconds; + $limit = (int)$limit; + $offset = (int)$offset; + + $time = time() - $seconds; + + $access = get_access_sql_suffix("e"); + + $query = "SELECT distinct e.* from {$CONFIG->dbprefix}entities e join {$CONFIG->dbprefix}users_entity u on e.guid = u.guid where u.last_action >= {$time} and $access order by u.last_action desc limit {$offset},{$limit}"; + + return get_data($query, "entity_row_to_elggstar"); +} + +/** + * Generate and send a password request email to a given user's registered email address. + * + * @param int $user_guid + */ +function send_new_password_request($user_guid) { + global $CONFIG; + + $user_guid = (int)$user_guid; + + $user = get_entity($user_guid); + if ($user) { + // generate code + $code = generate_random_cleartext_password(); + //create_metadata($user_guid, 'conf_code', $code,'', 0, ACCESS_PRIVATE); + set_private_setting($user_guid, 'passwd_conf_code', $code); + + // generate link + $link = $CONFIG->site->url . "action/user/passwordreset?u=$user_guid&c=$code"; + + // generate email + $email = sprintf(elgg_echo('email:resetreq:body'), $user->name, $_SERVER['REMOTE_ADDR'], $link); + + return notify_user($user->guid, $CONFIG->site->guid, elgg_echo('email:resetreq:subject'), $email, NULL, 'email'); } - /** - * Registers a user, returning false if the username already exists - * - * @param string $username The username of the new user - * @param string $password The password - * @param string $name The user's display name - * @param string $email Their email address - * @param bool $allow_multiple_emails Allow the same email address to be registered multiple times? - * @param int $friend_guid Optionally, GUID of a user this user will friend once fully registered - * @return int|false The new user's GUID; false on failure - */ - function register_user($username, $password, $name, $email, $allow_multiple_emails = false, $friend_guid = 0, $invitecode = '') { - - // Load the configuration - global $CONFIG; - - $username = trim($username); - // no need to trim password. - $password = $password; - $name = trim($name); - $email = trim($email); - - // A little sanity checking - if (empty($username) - || empty($password) - || empty($name) - || empty($email)) { - return false; - } + return false; +} + +/** + * Low level function to reset a given user's password. + * + * This can only be called from execute_new_password_request(). + * + * @param int $user_guid The user. + * @param string $password password text (which will then be converted into a hash and stored) + */ +function force_user_password_reset($user_guid, $password) { + global $CONFIG; + + if (call_gatekeeper('execute_new_password_request', __FILE__)) { + $user = get_entity($user_guid); - // See if it exists and is disabled - $access_status = access_get_show_hidden_status(); - access_show_hidden_entities(true); + if ($user) { + $salt = generate_random_cleartext_password(); // Reset the salt + $user->salt = $salt; - // Validate email address - if (!validate_email_address($email)) throw new RegistrationException(elgg_echo('registration:emailnotvalid')); + $hash = generate_user_password($user, $password); - // Validate password - if (!validate_password($password)) throw new RegistrationException(elgg_echo('registration:passwordnotvalid')); + return update_data("UPDATE {$CONFIG->dbprefix}users_entity set password='$hash', salt='$salt' where guid=$user_guid"); + } + } - // Validate the username - if (!validate_username($username)) throw new RegistrationException(elgg_echo('registration:usernamenotvalid')); + return false; +} - // Check to see if $username exists already - if ($user = get_user_by_username($username)) { - //return false; - throw new RegistrationException(elgg_echo('registration:userexists')); - } +/** + * Validate and execute a password reset for a user. + * + * @param int $user_guid The user id + * @param string $conf_code Confirmation code as sent in the request email. + */ +function execute_new_password_request($user_guid, $conf_code) { + global $CONFIG; - // If we're not allowed multiple emails then see if this address has been used before - if ((!$allow_multiple_emails) && (get_user_by_email($email))) - { - throw new RegistrationException(elgg_echo('registration:dupeemail')); - } + $user_guid = (int)$user_guid; - access_show_hidden_entities($access_status); - - // Check to see if we've registered the first admin yet. - // If not, this is the first admin user! - $admin = datalist_get('admin_registered'); - - // Otherwise ... - $user = new ElggUser(); - $user->username = $username; - $user->email = $email; - $user->name = $name; - $user->access_id = ACCESS_PUBLIC; - $user->salt = generate_random_cleartext_password(); // Note salt generated before password! - $user->password = generate_user_password($user, $password); - $user->owner_guid = 0; // Users aren't owned by anyone, even if they are admin created. - $user->container_guid = 0; // Users aren't contained by anyone, even if they are admin created. - $user->save(); - - // If $friend_guid has been set, make mutual friends - if ($friend_guid) { - if ($friend_user = get_user($friend_guid)) { - if ($invitecode == generate_invite_code($friend_user->username)) { - $user->addFriend($friend_guid); - $friend_user->addFriend($user->guid); - } - } - } + $user = get_entity($user_guid); + if (($user) && (get_private_setting($user_guid, 'passwd_conf_code') == $conf_code)) { + $password = generate_random_cleartext_password(); - global $registering_admin; - if (!$admin) { - $user->admin = true; - datalist_set('admin_registered',1); - $registering_admin = true; - } else { - $registering_admin = false; - } + if (force_user_password_reset($user_guid, $password)) { + //remove_metadata($user_guid, 'conf_code'); + remove_private_setting($user_guid, 'passwd_conf_code'); - // Turn on email notifications by default - set_user_notification_setting($user->getGUID(), 'email', true); + $email = sprintf(elgg_echo('email:resetpassword:body'), $user->name, $password); - return $user->getGUID(); + return notify_user($user->guid, $CONFIG->site->guid, elgg_echo('email:resetpassword:subject'), $email, NULL, 'email'); + } } - /** - * Generates a unique invite code for a user - * - * @param string $username The username of the user sending the invitation - * @return string Invite code - */ - function generate_invite_code($username) { + return false; +} + +/** + * Set the validation status for a user. + * + * @param bool $status Validated (true) or false + * @param string $method Optional method to say how a user was validated + * @return bool + */ +function set_user_validation_status($user_guid, $status, $method = '') { + if (!$status) { + $method = ''; + } - $secret = datalist_get('__site_secret__'); - return md5($username . $secret); + if ($status) { + if ( + (create_metadata($user_guid, 'validated', $status,'', 0, ACCESS_PUBLIC)) && + (create_metadata($user_guid, 'validated_method', $method,'', 0, ACCESS_PUBLIC)) + ) { + return true; + } + } else { + $validated = get_metadata_byname($user_guid, 'validated'); + $validated_method = get_metadata_byname($user_guid, 'validated_method'); + if ( + ($validated) && + ($validated_method) && + (delete_metadata($validated->id)) && + (delete_metadata($validated_method->id)) + ) + return true; } - /** - * Adds collection submenu items - * - */ - function collections_submenu_items() { - global $CONFIG; - $user = get_loggedin_user(); - add_submenu_item(elgg_echo('friends:collections'), $CONFIG->wwwroot . "pg/collections/" . $user->username); - add_submenu_item(elgg_echo('friends:collections:add'),$CONFIG->wwwroot."pg/collections/add"); + return false; +} + +/** + * Trigger an event requesting that a user guid be validated somehow - either by email address or some other way. + * + * This event invalidates any existing values and returns + * + * @param unknown_type $user_guid + */ +function request_user_validation($user_guid) { + $user = get_entity($user_guid); + + if (($user) && ($user instanceof ElggUser)) { + // invalidate any existing validations + set_user_validation_status($user_guid, false); + + // request validation + trigger_elgg_event('validate', 'user', $user); + } +} + +/** + * Validates an email address. + * + * @param string $address Email address. + * @return bool + */ +function is_email_address($address) { + // TODO: Make this better! + + if (strpos($address, '@')=== false) { + return false; } - /** - * Page handler for friends - * - */ - function friends_page_handler($page_elements) { - - if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) { - set_page_owner($user->getGUID()); - } - if ($_SESSION['guid'] == page_owner()) { - collections_submenu_items(); - } - require_once(dirname(dirname(dirname(__FILE__))) . "/friends/index.php"); - + if (strpos($address, '.')=== false) { + return false; } - /** - * Page handler for friends of - * - */ - function friends_of_page_handler($page_elements) { + return true; +} + +/** + * Simple function that will generate a random clear text password suitable for feeding into generate_user_password(). + * + * @see generate_user_password + * @return string + */ +function generate_random_cleartext_password() { + return substr(md5(microtime() . rand()), 0, 8); +} + +/** + * Generate a password for a user, currently uses MD5. + * + * Later may introduce salting etc. + * + * @param ElggUser $user The user this is being generated for. + * @param string $password Password in clear text + */ +function generate_user_password(ElggUser $user, $password) { + return md5($password . $user->salt); +} + +/** + * Simple function which ensures that a username contains only valid characters. + * + * This should only permit chars that are valid on the file system as well. + * + * @param string $username + * @throws RegistrationException on invalid + */ +function validate_username($username) { + global $CONFIG; + + // Basic, check length + if (!isset($CONFIG->minusername)) { + $CONFIG->minusername = 4; + } - if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) { - set_page_owner($user->getGUID()); - } - if ($_SESSION['guid'] == page_owner()) { - collections_submenu_items(); - } - require_once(dirname(dirname(dirname(__FILE__))) . "/friends/of.php"); + if (strlen($username) < $CONFIG->minusername) { + throw new RegistrationException(elgg_echo('registration:usernametooshort')); + } + // Blacklist for bad characters (partially nicked from mediawiki) + + $blacklist = '/[' . + '\x{0080}-\x{009f}' . # iso-8859-1 control chars + '\x{00a0}' . # non-breaking space + '\x{2000}-\x{200f}' . # various whitespace + '\x{2028}-\x{202f}' . # breaks and control chars + '\x{3000}' . # ideographic space + '\x{e000}-\x{f8ff}' . # private use + ']/u'; + + if ( + preg_match($blacklist, $username) + ) { + throw new RegistrationException(elgg_echo('registration:invalidchars')); } - /** - * Page handler for friends of - * - */ - function collections_page_handler($page_elements) { - - if (isset($page_elements[0])) { - if ($page_elements[0] == "add") { - set_page_owner($_SESSION['guid']); - collections_submenu_items(); - require_once(dirname(dirname(dirname(__FILE__))) . "/friends/add.php"); - } else { - if ($user = get_user_by_username($page_elements[0])) { - set_page_owner($user->getGUID()); - if ($_SESSION['guid'] == page_owner()) { - collections_submenu_items(); - } - require_once(dirname(dirname(dirname(__FILE__))) . "/friends/collections.php"); - } - } + // Belts and braces TODO: Tidy into main unicode + $blacklist2 = '/\\"\'*& ?#%^(){}[]~?<>;|¬`@-+='; + for ($n=0; $n < strlen($blacklist2); $n++) { + if (strpos($username, $blacklist2[$n])!==false) { + throw new RegistrationException(elgg_echo('registration:invalidchars')); } - } - /** - * Page handler for dashboard - */ - function dashboard_page_handler($page_elements) { - require_once(dirname(dirname(dirname(__FILE__))) . "/dashboard/index.php"); + $result = true; + return trigger_plugin_hook('registeruser:validate:username', 'all', array('username' => $username), $result); +} + +/** + * Simple validation of a password. + * + * @param string $password + * @throws RegistrationException on invalid + */ +function validate_password($password) { + if (strlen($password) < 6) { + throw new RegistrationException(elgg_echo('registration:passwordtooshort')); } - /** - * Sets the last action time of the given user to right now. - * - * @param int $user_guid The user GUID - */ - function set_last_action($user_guid) { - - $user_guid = (int) $user_guid; - global $CONFIG; - $time = time(); - - execute_delayed_write_query("UPDATE {$CONFIG->dbprefix}users_entity set prev_last_action = last_action, last_action = {$time} where guid = {$user_guid}"); - + $result = true; + return trigger_plugin_hook('registeruser:validate:password', 'all', array('password' => $password), $result); +} + +/** + * Simple validation of a email. + * + * @param string $address + * @throws RegistrationException on invalid + * @return bool + */ +function validate_email_address($address) { + if (!is_email_address($address)) { + throw new RegistrationException(elgg_echo('registration:notemail')); } - /** - * Sets the last logon time of the given user to right now. - * - * @param int $user_guid The user GUID - */ - function set_last_login($user_guid) { - - $user_guid = (int) $user_guid; - global $CONFIG; - $time = time(); + // Got here, so lets try a hook (defaulting to ok) + $result = true; + return trigger_plugin_hook('registeruser:validate:email', 'all', array('email' => $address), $result); +} + +/** + * Registers a user, returning false if the username already exists + * + * @param string $username The username of the new user + * @param string $password The password + * @param string $name The user's display name + * @param string $email Their email address + * @param bool $allow_multiple_emails Allow the same email address to be registered multiple times? + * @param int $friend_guid Optionally, GUID of a user this user will friend once fully registered + * @return int|false The new user's GUID; false on failure + */ +function register_user($username, $password, $name, $email, $allow_multiple_emails = false, $friend_guid = 0, $invitecode = '') { + // Load the configuration + global $CONFIG; + + $username = trim($username); + // no need to trim password. + $password = $password; + $name = trim($name); + $email = trim($email); + + // A little sanity checking + if (empty($username) + || empty($password) + || empty($name) + || empty($email)) { + return false; + } - execute_delayed_write_query("UPDATE {$CONFIG->dbprefix}users_entity set prev_last_login = last_login, last_login = {$time} where guid = {$user_guid}"); + // See if it exists and is disabled + $access_status = access_get_show_hidden_status(); + access_show_hidden_entities(true); + // Validate email address + if (!validate_email_address($email)) { + throw new RegistrationException(elgg_echo('registration:emailnotvalid')); } - /** - * A permissions plugin hook that grants access to users if they are newly created - allows - * for email activation. - * - * TODO: Do this in a better way! - * - * @param unknown_type $hook - * @param unknown_type $entity_type - * @param unknown_type $returnvalue - * @param unknown_type $params - */ - function new_user_enable_permissions_check($hook, $entity_type, $returnvalue, $params) - { - $entity = $params['entity']; - $user = $params['user']; - if (($entity) && ($entity instanceof ElggUser)) - { - if ( - (($entity->disable_reason == 'new_user') || ( - // if this isn't set at all they're a "new user" - !$entity->validated - )) - && (!isloggedin())) - return true; - - } + // Validate password + if (!validate_password($password)) { + throw new RegistrationException(elgg_echo('registration:passwordnotvalid')); + } - return $returnvalue; + // Validate the username + if (!validate_username($username)) { + throw new RegistrationException(elgg_echo('registration:usernamenotvalid')); } - /** - * Sets up user-related menu items - * - */ - function users_pagesetup() { + // Check to see if $username exists already + if ($user = get_user_by_username($username)) { + //return false; + throw new RegistrationException(elgg_echo('registration:userexists')); + } - // Load config - global $CONFIG; + // If we're not allowed multiple emails then see if this address has been used before + if ((!$allow_multiple_emails) && (get_user_by_email($email))) { + throw new RegistrationException(elgg_echo('registration:dupeemail')); + } - //add submenu options - if (get_context() == "friends" || - get_context() == "friendsof" || - get_context() == "collections") { - add_submenu_item(elgg_echo('friends'),$CONFIG->wwwroot."pg/friends/" . page_owner_entity()->username); - add_submenu_item(elgg_echo('friends:of'),$CONFIG->wwwroot."pg/friendsof/" . page_owner_entity()->username); + access_show_hidden_entities($access_status); + + // Check to see if we've registered the first admin yet. + // If not, this is the first admin user! + $admin = datalist_get('admin_registered'); + + // Otherwise ... + $user = new ElggUser(); + $user->username = $username; + $user->email = $email; + $user->name = $name; + $user->access_id = ACCESS_PUBLIC; + $user->salt = generate_random_cleartext_password(); // Note salt generated before password! + $user->password = generate_user_password($user, $password); + $user->owner_guid = 0; // Users aren't owned by anyone, even if they are admin created. + $user->container_guid = 0; // Users aren't contained by anyone, even if they are admin created. + $user->save(); + + // If $friend_guid has been set, make mutual friends + if ($friend_guid) { + if ($friend_user = get_user($friend_guid)) { + if ($invitecode == generate_invite_code($friend_user->username)) { + $user->addFriend($friend_guid); + $friend_user->addFriend($user->guid); } + } + } + global $registering_admin; + if (!$admin) { + $user->admin = true; + datalist_set('admin_registered',1); + $registering_admin = true; + } else { + $registering_admin = false; } - /** - * Users initialisation function, which establishes the page handler - * - */ - function users_init() { + // Turn on email notifications by default + set_user_notification_setting($user->getGUID(), 'email', true); + + return $user->getGUID(); +} + +/** + * Generates a unique invite code for a user + * + * @param string $username The username of the user sending the invitation + * @return string Invite code + */ +function generate_invite_code($username) { + $secret = datalist_get('__site_secret__'); + return md5($username . $secret); +} + +/** + * Adds collection submenu items + * + */ +function collections_submenu_items() { + global $CONFIG; + $user = get_loggedin_user(); + add_submenu_item(elgg_echo('friends:collections'), $CONFIG->wwwroot . "pg/collections/" . $user->username); + add_submenu_item(elgg_echo('friends:collections:add'),$CONFIG->wwwroot."pg/collections/add"); +} + +/** + * Page handler for friends + * + */ +function friends_page_handler($page_elements) { + if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) { + set_page_owner($user->getGUID()); + } + if ($_SESSION['guid'] == page_owner()) { + collections_submenu_items(); + } - // Load config - global $CONFIG; + require_once(dirname(dirname(dirname(__FILE__))) . "/friends/index.php"); +} - // Set up menu for logged in users - if (isloggedin()) { - $user = get_loggedin_user(); - add_menu(elgg_echo('friends'), $CONFIG->wwwroot . "pg/friends/" . $user->username); +/** + * Page handler for friends of + * + */ +function friends_of_page_handler($page_elements) { + if (isset($page_elements[0]) && $user = get_user_by_username($page_elements[0])) { + set_page_owner($user->getGUID()); + } + if ($_SESSION['guid'] == page_owner()) { + collections_submenu_items(); + } + require_once(dirname(dirname(dirname(__FILE__))) . "/friends/of.php"); +} + +/** + * Page handler for friends of + * + */ +function collections_page_handler($page_elements) { + if (isset($page_elements[0])) { + if ($page_elements[0] == "add") { + set_page_owner($_SESSION['guid']); + collections_submenu_items(); + require_once(dirname(dirname(dirname(__FILE__))) . "/friends/add.php"); + } else { + if ($user = get_user_by_username($page_elements[0])) { + set_page_owner($user->getGUID()); + if ($_SESSION['guid'] == page_owner()) { + collections_submenu_items(); + } + require_once(dirname(dirname(dirname(__FILE__))) . "/friends/collections.php"); } + } + } +} + +/** + * Page handler for dashboard + */ +function dashboard_page_handler($page_elements) { + require_once(dirname(dirname(dirname(__FILE__))) . "/dashboard/index.php"); +} + +/** + * Sets the last action time of the given user to right now. + * + * @param int $user_guid The user GUID + */ +function set_last_action($user_guid) { + $user_guid = (int) $user_guid; + global $CONFIG; + $time = time(); + + execute_delayed_write_query("UPDATE {$CONFIG->dbprefix}users_entity set prev_last_action = last_action, last_action = {$time} where guid = {$user_guid}"); +} + +/** + * Sets the last logon time of the given user to right now. + * + * @param int $user_guid The user GUID + */ +function set_last_login($user_guid) { + $user_guid = (int) $user_guid; + global $CONFIG; + $time = time(); + + execute_delayed_write_query("UPDATE {$CONFIG->dbprefix}users_entity set prev_last_login = last_login, last_login = {$time} where guid = {$user_guid}"); +} + +/** + * A permissions plugin hook that grants access to users if they are newly created - allows + * for email activation. + * + * TODO: Do this in a better way! + * + * @param unknown_type $hook + * @param unknown_type $entity_type + * @param unknown_type $returnvalue + * @param unknown_type $params + */ +function new_user_enable_permissions_check($hook, $entity_type, $returnvalue, $params) { + $entity = $params['entity']; + $user = $params['user']; + if (($entity) && ($entity instanceof ElggUser)) { + if ( + (($entity->disable_reason == 'new_user') || ( + // if this isn't set at all they're a "new user" + !$entity->validated + )) + && (!isloggedin())) { + return true; + } + } - register_page_handler('friends','friends_page_handler'); - register_page_handler('friendsof','friends_of_page_handler'); - register_page_handler('collections','collections_page_handler'); - register_page_handler('dashboard','dashboard_page_handler'); - register_action("register",true); - register_action("useradd",true); - register_action("friends/add"); - register_action("friends/remove"); - register_action('friends/addcollection'); - register_action('friends/deletecollection'); - register_action('friends/editcollection'); - register_action("user/spotlight"); + return $returnvalue; +} + +/** + * Sets up user-related menu items + * + */ +function users_pagesetup() { + // Load config + global $CONFIG; + + //add submenu options + if (get_context() == "friends" || get_context() == "friendsof" || get_context() == "collections") { + add_submenu_item(elgg_echo('friends'),$CONFIG->wwwroot."pg/friends/" . page_owner_entity()->username); + add_submenu_item(elgg_echo('friends:of'),$CONFIG->wwwroot."pg/friendsof/" . page_owner_entity()->username); + } +} + +/** + * Users initialisation function, which establishes the page handler + * + */ +function users_init() { + // Load config + global $CONFIG; + + // Set up menu for logged in users + if (isloggedin()) { + $user = get_loggedin_user(); + add_menu(elgg_echo('friends'), $CONFIG->wwwroot . "pg/friends/" . $user->username); + } - register_action("usersettings/save"); + register_page_handler('friends','friends_page_handler'); + register_page_handler('friendsof','friends_of_page_handler'); + register_page_handler('collections','collections_page_handler'); + register_page_handler('dashboard','dashboard_page_handler'); + register_action("register",true); + register_action("useradd",true); + register_action("friends/add"); + register_action("friends/remove"); + register_action('friends/addcollection'); + register_action('friends/deletecollection'); + register_action('friends/editcollection'); + register_action("user/spotlight"); - register_action("user/passwordreset"); - register_action("user/requestnewpassword"); + register_action("usersettings/save"); - // User name change - extend_elgg_settings_page('user/settings/name', 'usersettings/user', 1); - //register_action("user/name"); + register_action("user/passwordreset"); + register_action("user/requestnewpassword"); - // User password change - extend_elgg_settings_page('user/settings/password', 'usersettings/user', 1); - //register_action("user/password"); + // User name change + extend_elgg_settings_page('user/settings/name', 'usersettings/user', 1); + //register_action("user/name"); - // Add email settings - extend_elgg_settings_page('user/settings/email', 'usersettings/user', 1); - //register_action("email/save"); + // User password change + extend_elgg_settings_page('user/settings/password', 'usersettings/user', 1); + //register_action("user/password"); - // Add language settings - extend_elgg_settings_page('user/settings/language', 'usersettings/user', 1); + // Add email settings + extend_elgg_settings_page('user/settings/email', 'usersettings/user', 1); + //register_action("email/save"); - // Add default access settings - extend_elgg_settings_page('user/settings/default_access', 'usersettings/user', 1); + // Add language settings + extend_elgg_settings_page('user/settings/language', 'usersettings/user', 1); - //register_action("user/language"); + // Add default access settings + extend_elgg_settings_page('user/settings/default_access', 'usersettings/user', 1); - // Register the user type - register_entity_type('user',''); + //register_action("user/language"); - register_plugin_hook('usersettings:save','user','users_settings_save'); - register_plugin_hook('search','all','search_list_users_by_name'); + // Register the user type + register_entity_type('user',''); + register_plugin_hook('usersettings:save','user','users_settings_save'); + register_plugin_hook('search','all','search_list_users_by_name'); - // Handle a special case for newly created users when the user is not logged in - // TODO: handle this better! - register_plugin_hook('permissions_check','all','new_user_enable_permissions_check'); - } - /** - * Returns a formatted list of users suitable for injecting into search. - * - */ - function search_list_users_by_name($hook, $user, $returnvalue, $tag) { + // Handle a special case for newly created users when the user is not logged in + // TODO: handle this better! + register_plugin_hook('permissions_check','all','new_user_enable_permissions_check'); +} - // Change this to set the number of users that display on the search page - $threshold = 4; +/** + * Returns a formatted list of users suitable for injecting into search. + * + */ +function search_list_users_by_name($hook, $user, $returnvalue, $tag) { + // Change this to set the number of users that display on the search page + $threshold = 4; - $object = get_input('object'); + $object = get_input('object'); - if (!get_input('offset') && (empty($object) || $object == 'user')) + if (!get_input('offset') && (empty($object) || $object == 'user')) { if ($users = search_for_user($tag,$threshold)) { - $countusers = search_for_user($tag,0,0,"",true); $return = elgg_view('user/search/startblurb',array('count' => $countusers, 'tag' => $tag)); @@ -1545,23 +1538,18 @@ return $return; } - - } - - function users_settings_save() { - - global $CONFIG; - include($CONFIG->path . "actions/user/name.php"); - include($CONFIG->path . "actions/user/password.php"); - include($CONFIG->path . "actions/email/save.php"); - include($CONFIG->path . "actions/user/language.php"); - include($CONFIG->path . "actions/user/default_access.php"); - } - - //register actions ************************************************************* - - register_elgg_event_handler('init','system','users_init',0); - register_elgg_event_handler('pagesetup','system','users_pagesetup',0); - -?> \ No newline at end of file +} + +function users_settings_save() { + global $CONFIG; + include($CONFIG->path . "actions/user/name.php"); + include($CONFIG->path . "actions/user/password.php"); + include($CONFIG->path . "actions/email/save.php"); + include($CONFIG->path . "actions/user/language.php"); + include($CONFIG->path . "actions/user/default_access.php"); +} + +//register actions ************************************************************* +register_elgg_event_handler('init','system','users_init',0); +register_elgg_event_handler('pagesetup','system','users_pagesetup',0); diff --git a/engine/lib/usersettings.php b/engine/lib/usersettings.php index 5a562540f..24a956a62 100644 --- a/engine/lib/usersettings.php +++ b/engine/lib/usersettings.php @@ -1,84 +1,77 @@ wwwroot . "pg/settings/user/{$user->username}/"); - //add_submenu_item(elgg_echo('profile:editicon'), $CONFIG->wwwroot . 'mod/profile/editicon.php'); - add_submenu_item(elgg_echo('usersettings:plugins:opt:linktext'),$CONFIG->wwwroot . "pg/settings/plugins/{$user->username}/"); - add_submenu_item(elgg_echo('usersettings:statistics:opt:linktext'),$CONFIG->wwwroot . "pg/settings/statistics/{$user->username}/"); - } + // Menu options + if (get_context() == "settings") { + $user = get_loggedin_user(); + add_submenu_item(elgg_echo('usersettings:user:opt:linktext'),$CONFIG->wwwroot . "pg/settings/user/{$user->username}/"); + //add_submenu_item(elgg_echo('profile:editicon'), $CONFIG->wwwroot . 'mod/profile/editicon.php'); + add_submenu_item(elgg_echo('usersettings:plugins:opt:linktext'),$CONFIG->wwwroot . "pg/settings/plugins/{$user->username}/"); + add_submenu_item(elgg_echo('usersettings:statistics:opt:linktext'),$CONFIG->wwwroot . "pg/settings/statistics/{$user->username}/"); } - - function usersettings_page_handler($page) - { - global $CONFIG; - - $path = $CONFIG->path . "settings/index.php"; - - if ($page[0]) - { - switch ($page[0]) - { - case 'user' : $path = $CONFIG->path . "settings/user.php"; break; - case 'statistics' : $path = $CONFIG->path . "settings/statistics.php"; break; - case 'plugins' : $path = $CONFIG->path . "settings/plugins.php"; break; - } +} + +function usersettings_page_handler($page) { + global $CONFIG; + + $path = $CONFIG->path . "settings/index.php"; + + if ($page[0]) { + switch ($page[0]) { + case 'user' : $path = $CONFIG->path . "settings/user.php"; break; + case 'statistics' : $path = $CONFIG->path . "settings/statistics.php"; break; + case 'plugins' : $path = $CONFIG->path . "settings/plugins.php"; break; } - - if ($page[1]) - set_input('username', $page[1]); - - include($path); } - - /** - * Initialise the admin page. - */ - function usersettings_init() - { - // Page handler - register_page_handler('settings','usersettings_page_handler'); + + if ($page[1]) { + set_input('username', $page[1]); } - - /// Register init function - register_elgg_event_handler('init','system','usersettings_init'); - register_elgg_event_handler('pagesetup','system','usersettings_pagesetup'); - -?> \ No newline at end of file + + include($path); +} + +/** + * Initialise the admin page. + */ +function usersettings_init() { + // Page handler + register_page_handler('settings','usersettings_page_handler'); +} + +/// Register init function +register_elgg_event_handler('init','system','usersettings_init'); +register_elgg_event_handler('pagesetup','system','usersettings_pagesetup'); \ No newline at end of file diff --git a/engine/lib/version.php b/engine/lib/version.php index 8251efe67..3728fb8ec 100644 --- a/engine/lib/version.php +++ b/engine/lib/version.php @@ -1,128 +1,117 @@ path . 'engine/lib/upgrades/')) { - - $upgrades = array(); - - while ($updatefile = readdir($handle)) { - - // Look for upgrades and add to upgrades list - if (!is_dir($CONFIG->path . 'engine/lib/upgrades/' . $updatefile)) { - if (preg_match('/([0-9]*)\.php/',$updatefile,$matches)) { - $core_version = (int) $matches[1]; - if ($core_version > $version) { - $upgrades[] = $updatefile; - } - } - } - - } - - // Sort and execute - asort($upgrades); - if (sizeof($upgrades) > 0) { - foreach($upgrades as $upgrade) { - try { - include($CONFIG->path . 'engine/lib/upgrades/' . $upgrade); - } catch (Exception $e) { - error_log($e->getmessage()); - } - - } - } - - return true; - } - - return false; +/** + * Run any php upgrade scripts which are required + * + * @param unknown_type $version + */ +function upgrade_code($version) { + global $CONFIG; + + // Elgg and its database must be installed to upgrade it! + if (!is_db_installed() || !is_installed()) { + return false; } - /** - * Get the current version information - * - * @param true|false $humanreadable Whether to return a human readable version (default: false) - * @return string|false Depending on success - */ - function get_version($humanreadable = false) { - - global $CONFIG; - if (include($CONFIG->path . "version.php")) { - if (!$humanreadable) return $version; - return $release; + $version = (int) $version; + + if ($handle = opendir($CONFIG->path . 'engine/lib/upgrades/')) { + $upgrades = array(); + + while ($updatefile = readdir($handle)) { + // Look for upgrades and add to upgrades list + if (!is_dir($CONFIG->path . 'engine/lib/upgrades/' . $updatefile)) { + if (preg_match('/([0-9]*)\.php/',$updatefile,$matches)) { + $core_version = (int) $matches[1]; + if ($core_version > $version) { + $upgrades[] = $updatefile; + } + } } - - return false; - } - - /** - * Determines whether or not the database needs to be upgraded. - * - * @return true|false Depending on whether or not the db version matches the code version - */ - function version_upgrade_check() { - - $dbversion = (int) datalist_get('version'); - $version = get_version(); - - if ($version > $dbversion) { - return true; + + // Sort and execute + asort($upgrades); + if (sizeof($upgrades) > 0) { + foreach($upgrades as $upgrade) { + try { + include($CONFIG->path . 'engine/lib/upgrades/' . $upgrade); + } catch (Exception $e) { + error_log($e->getmessage()); + } } - return false; - - } - - /** - * Upgrades Elgg - * - */ - function version_upgrade() { - - $dbversion = (int) datalist_get('version'); - - // Upgrade database - db_upgrade($dbversion); - system_message(elgg_echo('upgrade:db')); - - // Upgrade core - if (upgrade_code($dbversion)) - system_message(elgg_echo('upgrade:core')); - - // Now we trigger an event to give the option for plugins to do something - $upgrade_details = stdClass; - $upgrade_details->from = $dbversion; - $upgrade_details->to = get_version(); - - trigger_elgg_event('upgrade', 'upgrade', $upgrade_details); - - // Update the version - datalist_set('version', get_version()); - } - -?> \ No newline at end of file + + return true; + } + + return false; +} + +/** + * Get the current version information + * + * @param true|false $humanreadable Whether to return a human readable version (default: false) + * @return string|false Depending on success + */ +function get_version($humanreadable = false) { + global $CONFIG; + + if (include($CONFIG->path . "version.php")) { + if (!$humanreadable) return $version; + return $release; + } + + return false; +} + +/** + * Determines whether or not the database needs to be upgraded. + * + * @return true|false Depending on whether or not the db version matches the code version + */ +function version_upgrade_check() { + $dbversion = (int) datalist_get('version'); + $version = get_version(); + + if ($version > $dbversion) { + return true; + } + + return false; +} + +/** + * Upgrades Elgg + * + */ +function version_upgrade() { + $dbversion = (int) datalist_get('version'); + + // Upgrade database + db_upgrade($dbversion); + system_message(elgg_echo('upgrade:db')); + + // Upgrade core + if (upgrade_code($dbversion)) { + system_message(elgg_echo('upgrade:core')); + } + + // Now we trigger an event to give the option for plugins to do something + $upgrade_details = stdClass; + $upgrade_details->from = $dbversion; + $upgrade_details->to = get_version(); + + trigger_elgg_event('upgrade', 'upgrade', $upgrade_details); + + // Update the version + datalist_set('version', get_version()); +} diff --git a/engine/lib/widgets.php b/engine/lib/widgets.php index f6f01f660..7adf5ffad 100644 --- a/engine/lib/widgets.php +++ b/engine/lib/widgets.php @@ -3,7 +3,7 @@ /** * Elgg widgets library. * Contains code for handling widgets. - * + * * @package Elgg * @subpackage Core @@ -19,12 +19,12 @@ protected function initialise_attributes() { parent::initialise_attributes(); - + $this->attributes['subtype'] = "widget"; } public function __construct($guid = null) { parent::__construct($guid); } - + /** * Override entity get and sets in order to save data to private data store. */ @@ -34,12 +34,12 @@ if (isset($this->attributes[$name])) { return $this->attributes[$name]; } - + // No, so see if its in the private data store. $meta = get_private_setting($this->guid, $name); if ($meta) return $meta; - + // Can't find it, so return null return null; } @@ -51,15 +51,15 @@ { if (array_key_exists($name, $this->attributes)) { - // Check that we're not trying to change the guid! + // Check that we're not trying to change the guid! if ((array_key_exists('guid', $this->attributes)) && ($name=='guid')) return false; - + $this->attributes[$name] = $value; } - else + else return set_private_setting($this->guid, $name, $value); - + return true; } } @@ -70,7 +70,7 @@ * @param string $context The context we wish to enable context for */ function use_widgets($context) { - + global $CONFIG; if (!isset($CONFIG->widgets)) $CONFIG->widgets = new stdClass; @@ -80,26 +80,26 @@ if (!empty($context)) { $CONFIG->widgets->contexts[] = $context; } - + } - + /** * Determines whether or not the current context is using widgets * * @return true|false Depending on widget status */ function using_widgets() { - + global $CONFIG; $context = get_context(); if (isset($CONFIG->widgets->contexts) && is_array($CONFIG->widgets->contexts)) { if (in_array($context, $CONFIG->widgets->contexts)) return true; } - + return false; - + } - + /** * When given a widget entity and a new requested location, saves the new location * and also provides a sensible ordering for all widgets in that column @@ -110,58 +110,58 @@ * @return true|false Depending on success */ function save_widget_location(ElggObject $widget, $order, $column) { - + if ($widget instanceof ElggObject) { if ($widget->subtype == "widget") { - + // If you can't move the widget, don't save a new location if (!$widget->draggable) return false; - + // Sanitise the column value if ($column != 1 || $column != 2 || $column != 3) $column = 1; - + $widget->column = (int) $column; - + $ordertmp = array(); - - if ($entities = get_entities_from_metadata_multi(array( + + if ($entities = get_entities_from_metadata_multi(array( 'context' => $widget->context, 'column' => $column, ),'object','widget')) { foreach($entities as $entity) { $entityorder = $entity->order; if ($entityorder < $order) { - $ordertmp[$entityorder] = $entity; + $ordertmp[$entityorder] = $entity; } if ($entityorder >= $order) { $ordertmp[$entityorder + 10000] = $entity; } - } + } } - + $ordertmp[$order] = $widget; ksort($ordertmp); - + $orderticker = 10; foreach($ordertmp as $orderval => $entity) { $entity->order = $orderticker; $orderticker += 10; } - + return true; - + } else { register_error($widget->subtype); } - + } - + return false; - + } - + /** * Get widgets for a particular context and column, in order of display * @@ -171,34 +171,34 @@ * @return array|false An array of widget ElggObjects, or false */ function get_widgets($user_guid, $context, $column) { - + if ($widgets = get_entities_from_private_setting_multi(array( 'column' => $column, 'context' => $context), "object", "widget", $user_guid, "", 10000)) /*if ($widgets = get_user_objects_by_metadata($user_guid, "widget", array( 'column' => $column, - 'context' => $context, + 'context' => $context, ), 10000)) { */ { - + $widgetorder = array(); foreach($widgets as $widget) { $order = $widget->order; while(isset($widgetorder[$order])) { $order++; } - $widgetorder[$order] = $widget; + $widgetorder[$order] = $widget; } - + ksort($widgetorder); - + return $widgetorder; - + } - + return false; - + } /** @@ -208,11 +208,11 @@ * @return string The HTML for the widget, including JavaScript wrapper */ function display_widget(ElggObject $widget) { - + return elgg_view_entity($widget); - + } - + /** * Add a new widget * @@ -225,12 +225,12 @@ * @return true|false Depending on success */ function add_widget($user_guid, $handler, $context, $order = 0, $column = 1, $access_id = null) { - + if (empty($user_guid) || empty($context) || empty($handler) || !widget_type_exists($handler)) return false; - + if ($user = get_user($user_guid)) { - + $widget = new ElggWidget; $widget->owner_guid = $user_guid; $widget->container_guid = $user_guid; @@ -242,21 +242,21 @@ if (!$widget->save()) return false; - + $widget->handler = $handler; $widget->context = $context; $widget->column = $column; $widget->order = $order; - + // save_widget_location($widget, $order, $column); return true; - + } - + return false; - + } - + /** * Define a new widget type * @@ -268,36 +268,36 @@ * @param string $position A comma-separated list of positions on the page (side or main) where this widget is allowed (default: "side,main") * @return true|false Depending on success */ - + function add_widget_type($handler, $name, $description, $context = "all", $multiple = false, $positions = "side,main") { if (!empty($handler) && !empty($name)) { - + global $CONFIG; - + if (!isset($CONFIG->widgets)) $CONFIG->widgets = new stdClass; - + if (!isset($CONFIG->widgets->handlers)) $CONFIG->widgets->handlers = array(); - + $handlerobj = new stdClass; $handlerobj->name = $name; $handlerobj->description = $description; $handlerobj->context = explode(",",$context); $handlerobj->multiple = $multiple; $handlerobj->positions = explode(",",$positions); - + $CONFIG->widgets->handlers[$handler] = $handlerobj; return true; - + } - + return false; - + } - + /** * Determines whether or not widgets with the specified handler have been defined * @@ -305,69 +305,69 @@ * @return true|false Whether or not those widgets exist */ function widget_type_exists($handler) { - + global $CONFIG; - if (!empty($CONFIG->widgets) - && !empty($CONFIG->widgets->handlers) - && is_array($CONFIG->widgets->handlers) + if (!empty($CONFIG->widgets) + && !empty($CONFIG->widgets->handlers) + && is_array($CONFIG->widgets->handlers) && array_key_exists($handler, $CONFIG->widgets->handlers)) return true; return false; - + } - + /** * Returns an array of stdClass objects representing the defined widget types * * @return array A list of types defined (if any) */ function get_widget_types() { - + global $CONFIG; - if (!empty($CONFIG->widgets) - && !empty($CONFIG->widgets->handlers) + if (!empty($CONFIG->widgets) + && !empty($CONFIG->widgets->handlers) && is_array($CONFIG->widgets->handlers)) { - + $context = get_context(); - + foreach($CONFIG->widgets->handlers as $key => $handler) { if (!in_array('all',$handler->context) && !in_array($context,$handler->context)) { unset($CONFIG->widgets->handlers[$key]); } } - + return $CONFIG->widgets->handlers; - + } - + return array(); - + } - + /** * Saves a widget's settings (by passing an array of (name => value) pairs to save_{$handler}_widget) * * @param int $widget_guid The GUID of the widget we're saving to - * @param array $params An array of name => value parameters + * @param array $params An array of name => value parameters */ function save_widget_info($widget_guid, $params) { - + if ($widget = get_entity($widget_guid)) { - + $subtype = $widget->getSubtype(); - + if ($subtype != "widget") return false; $handler = $widget->handler; if (empty($handler) || !widget_type_exists($handler)) return false; - + if (!$widget->canEdit()) return false; - - // Save the params to the widget + + // Save the params to the widget if (is_array($params) && sizeof($params) > 0) { foreach($params as $name => $value) { - + if (!empty($name) && !in_array($name,array( 'guid','owner_guid','site_guid' ))) { @@ -381,34 +381,34 @@ } $widget->save(); } - + $function = "save_{$handler}_widget"; if (is_callable($function)) { return $function($params); } - + return true; - + } - + return false; - + } - + function reorder_widgets_from_panel($panelstring1, $panelstring2, $panelstring3, $context, $owner) { - + $return = true; - + $mainwidgets = explode('::',$panelstring1); $sidewidgets = explode('::',$panelstring2); $rightwidgets = explode('::',$panelstring3); - + $handlers = array(); $guids = array(); - + if (is_array($mainwidgets) && sizeof($mainwidgets) > 0) { foreach($mainwidgets as $widget) { - + $guid = (int) $widget; if ("{$guid}" == "{$widget}") { @@ -416,12 +416,12 @@ } else { $handlers[1][] = $widget; } - + } } if (is_array($sidewidgets) && sizeof($sidewidgets) > 0) { foreach($sidewidgets as $widget) { - + $guid = (int) $widget; if ("{$guid}" == "{$widget}") { @@ -429,12 +429,12 @@ } else { $handlers[2][] = $widget; } - + } } if (is_array($rightwidgets) && sizeof($rightwidgets) > 0) { foreach($rightwidgets as $widget) { - + $guid = (int) $widget; if ("{$guid}" == "{$widget}") { @@ -442,14 +442,14 @@ } else { $handlers[3][] = $widget; } - + } } - + // Reorder existing widgets or delete ones that have vanished foreach (array(1,2,3) as $column) { if ($dbwidgets = get_widgets($owner,$context,$column)) { - + foreach($dbwidgets as $dbwidget) { if (in_array($dbwidget->getGUID(),$guids[1]) || in_array($dbwidget->getGUID(),$guids[2]) || in_array($dbwidget->getGUID(),$guids[3])) { if (in_array($dbwidget->getGUID(),$guids[1])) { @@ -475,7 +475,7 @@ } } } - + } // Add new ones if (sizeof($guids[$column]) > 0) { @@ -489,11 +489,11 @@ } } } - + return $return; - + } - + /** * Run some things once. * @@ -501,7 +501,7 @@ function widget_run_once() { // Register a class - add_subtype("object", "widget", "ElggWidget"); + add_subtype("object", "widget", "ElggWidget"); } /** @@ -509,15 +509,15 @@ * */ function widgets_init() { - + register_action('widgets/reorder'); register_action('widgets/save'); register_action('widgets/add'); - + // Now run this stuff, but only once run_function_once("widget_run_once"); } - + // Register event register_elgg_event_handler('init','system','widgets_init'); -- cgit v1.2.3