diff options
-rw-r--r-- | actions/friends/collections/add.php | 2 | ||||
-rw-r--r-- | engine/classes/ElggTranslit.php | 15 | ||||
-rw-r--r-- | engine/lib/output.php | 8 | ||||
-rw-r--r-- | engine/tests/regression/trac_bugs.php | 16 | ||||
-rw-r--r-- | mod/messages/start.php | 36 | ||||
-rw-r--r-- | mod/search/search_hooks.php | 93 | ||||
-rw-r--r-- | views/default/css/admin.php | 2 | ||||
-rw-r--r-- | views/default/css/elements/navigation.php | 2 | ||||
-rw-r--r-- | views/default/output/access.php | 2 |
9 files changed, 109 insertions, 67 deletions
diff --git a/actions/friends/collections/add.php b/actions/friends/collections/add.php index 9dc17b37e..e63a149f7 100644 --- a/actions/friends/collections/add.php +++ b/actions/friends/collections/add.php @@ -6,7 +6,7 @@ * @subpackage Friends.Collections */ -$collection_name = get_input('collection_name'); +$collection_name = htmlspecialchars(get_input('collection_name', '', false), ENT_QUOTES, 'UTF-8'); $friends = get_input('friends_collection'); if (!$collection_name) { diff --git a/engine/classes/ElggTranslit.php b/engine/classes/ElggTranslit.php index 601965c11..4ae1d2479 100644 --- a/engine/classes/ElggTranslit.php +++ b/engine/classes/ElggTranslit.php @@ -49,10 +49,19 @@ class ElggTranslit { // Internationalization, AND 日本語! $string = self::transliterateAscii($string); - // more translation + // allow HTML tags in titles + $string = preg_replace('~<([a-zA-Z][^>]*)>~', ' $1 ', $string); + + // more substitutions + // @todo put these somewhere else $string = strtr($string, array( - // Euro/GBP - "\xE2\x82\xAC" /* € */ => 'E', "\xC2\xA3" /* £ */ => 'GBP', + // currency + "\xE2\x82\xAC" /* € */ => ' E ', + "\xC2\xA3" /* £ */ => ' GBP ', + + "&" => ' and ', + ">" => ' greater than ', + "<" => ' less than ', )); // remove all ASCII except 0-9a-zA-Z, hyphen, underscore, and whitespace diff --git a/engine/lib/output.php b/engine/lib/output.php index da8e1ab86..c5a04989b 100644 --- a/engine/lib/output.php +++ b/engine/lib/output.php @@ -284,11 +284,9 @@ function elgg_get_friendly_title($title) { return $result; } - // handle some special cases - $title = str_replace('&', 'and', $title); - // quotes and angle brackets stored in the database as html encoded - $title = htmlspecialchars_decode($title); - + // titles are often stored HTML encoded + $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8'); + $title = ElggTranslit::urlize($title); return $title; diff --git a/engine/tests/regression/trac_bugs.php b/engine/tests/regression/trac_bugs.php index 691433a41..58444dd39 100644 --- a/engine/tests/regression/trac_bugs.php +++ b/engine/tests/regression/trac_bugs.php @@ -206,21 +206,23 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest { */ public function test_friendly_title() { $cases = array( + // acid test + "B&N > Amazon, OK? <bold> 'hey!' $34" + => "b-and-n-greater-than-amazon-ok-bold-hey-34", + // hyphen, underscore and ASCII whitespace replaced by separator, // other non-alphanumeric ASCII removed - "a-a_a a\na\ra\ta\va!a\"a#a\$a%a&a'a(a)a*a+a,a.a/a:a;a<a=a>a?a@a[a\\a]a^a`a{a|a}a~a" - => "a-a-a-a-a-a-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - + "a-a_a a\na\ra\ta\va!a\"a#a\$a%a&a'a(a)a*a+a,a.a/a:a;a=a?a@a[a\\a]a^a`a{a|a}a~a" + => "a-a-a-a-a-a-aaaaaaa-and-aaaaaaaaaaaaaaaaaaaaaaa", + // separators trimmed - "-_ hello _-" => "hello", + "-_ hello _-" + => "hello", // accents removed, lower case, other multibyte chars are URL encoded "I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n, AND \xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" // Iñtërnâtiônàlizætiøn, AND 日本語 => 'internationalizaetion-and-%E6%97%A5%E6%9C%AC%E8%AA%9E', - - // some HTML entity replacements - "Me & You" => 'me-and-you', ); // where available, string is converted to NFC before transliteration diff --git a/mod/messages/start.php b/mod/messages/start.php index 5503a675a..6d0e82744 100644 --- a/mod/messages/start.php +++ b/mod/messages/start.php @@ -51,6 +51,9 @@ function messages_init() { elgg_register_plugin_hook_handler('notify:entity:message', 'object', 'messages_notification_msg'); register_notification_object('object', 'messages', elgg_echo('messages:new')); + // delete messages sent by a user when user is deleted + elgg_register_event_handler('delete', 'user', 'messages_purge'); + // ecml elgg_register_plugin_hook_handler('get_views', 'ecml', 'messages_ecml_views_hook'); @@ -425,6 +428,39 @@ function messages_user_hover_menu($hook, $type, $return, $params) { return $return; } +/** + * Delete messages from a user who is being deleted + * + * @param string $event Event name + * @param string $type Event type + * @param ElggUser $user User being deleted + */ +function messages_purge($event, $type, $user) { + + if (!$user->getGUID()) { + return; + } + + // make sure we delete them all + $entity_disable_override = access_get_show_hidden_status(); + access_show_hidden_entities(true); + $ia = elgg_set_ignore_access(true); + + $options = array( + 'type' => 'object', + 'subtype' => 'messages', + 'metadata_name' => 'fromId', + 'metadata_value' => $user->getGUID(), + 'limit' => 0, + ); + $batch = new ElggBatch('elgg_get_entities_from_metadata', $options); + foreach ($batch as $e) { + $e->delete(); + } + + elgg_set_ignore_access($ia); + access_show_hidden_entities($entity_disable_override); +} /** * Register messages with ECML. diff --git a/mod/search/search_hooks.php b/mod/search/search_hooks.php index 92c6d700a..c92003c7e 100644 --- a/mod/search/search_hooks.php +++ b/mod/search/search_hooks.php @@ -3,17 +3,17 @@ * Elgg core search. * * @package Elgg - * @subpackage Core + * @subpackage Search */ /** - * Return default results for searches on objects. + * Get objects that match the search parameters. * - * @param unknown_type $hook - * @param unknown_type $type - * @param unknown_type $value - * @param unknown_type $params - * @return unknown_type + * @param string $hook Hook name + * @param string $type Hook type + * @param array $value Empty array + * @param array $params Search parameters + * @return array */ function search_objects_hook($hook, $type, $value, $params) { @@ -23,7 +23,7 @@ function search_objects_hook($hook, $type, $value, $params) { $params['joins'] = array($join); $fields = array('title', 'description'); - $where = search_get_where_sql('oe', $fields, $params, FALSE); + $where = search_get_where_sql('oe', $fields, $params); $params['wheres'] = array($where); $params['count'] = TRUE; @@ -54,13 +54,13 @@ function search_objects_hook($hook, $type, $value, $params) { } /** - * Return default results for searches on groups. + * Get groups that match the search parameters. * - * @param unknown_type $hook - * @param unknown_type $type - * @param unknown_type $value - * @param unknown_type $params - * @return unknown_type + * @param string $hook Hook name + * @param string $type Hook type + * @param array $value Empty array + * @param array $params Search parameters + * @return array */ function search_groups_hook($hook, $type, $value, $params) { $db_prefix = elgg_get_config('dbprefix'); @@ -69,12 +69,9 @@ function search_groups_hook($hook, $type, $value, $params) { $join = "JOIN {$db_prefix}groups_entity ge ON e.guid = ge.guid"; $params['joins'] = array($join); - $fields = array('name', 'description'); - // force into boolean mode because we've having problems with the - // "if > 50% match 0 sets are returns" problem. - $where = search_get_where_sql('ge', $fields, $params, FALSE); + $where = search_get_where_sql('ge', $fields, $params); $params['wheres'] = array($where); @@ -109,15 +106,15 @@ function search_groups_hook($hook, $type, $value, $params) { } /** - * Return default results for searches on users. - * - * @todo add profile field MD searching + * Get users that match the search parameters. * - * @param unknown_type $hook - * @param unknown_type $type - * @param unknown_type $value - * @param unknown_type $params - * @return unknown_type + * Searches on username, display name, and profile fields + * + * @param string $hook Hook name + * @param string $type Hook type + * @param array $value Empty array + * @param array $params Search parameters + * @return array */ function search_users_hook($hook, $type, $value, $params) { $db_prefix = elgg_get_config('dbprefix'); @@ -205,13 +202,13 @@ function search_users_hook($hook, $type, $value, $params) { } /** - * Return default results for searches on tags. + * Get entities with tags that match the search parameters. * - * @param unknown_type $hook - * @param unknown_type $type - * @param unknown_type $value - * @param unknown_type $params - * @return unknown_type + * @param string $hook Hook name + * @param string $type Hook type + * @param array $value Empty array + * @param array $params Search parameters + * @return array */ function search_tags_hook($hook, $type, $value, $params) { $db_prefix = elgg_get_config('dbprefix'); @@ -340,11 +337,11 @@ function search_tags_hook($hook, $type, $value, $params) { /** * Register tags as a custom search type. * - * @param unknown_type $hook - * @param unknown_type $type - * @param unknown_type $value - * @param unknown_type $params - * @return unknown_type + * @param string $hook Hook name + * @param string $type Hook type + * @param array $value Array of custom search types + * @param array $params Search parameters + * @return array */ function search_custom_types_tags_hook($hook, $type, $value, $params) { $value[] = 'tags'; @@ -353,13 +350,13 @@ function search_custom_types_tags_hook($hook, $type, $value, $params) { /** - * Return default results for searches on comments. + * Get comments that match the search parameters. * - * @param unknown_type $hook - * @param unknown_type $type - * @param unknown_type $value - * @param unknown_type $params - * @return unknown_type + * @param string $hook Hook name + * @param string $type Hook type + * @param array $value Empty array + * @param array $params Search parameters + * @return array */ function search_comments_hook($hook, $type, $value, $params) { $db_prefix = elgg_get_config('dbprefix'); @@ -469,11 +466,11 @@ function search_comments_hook($hook, $type, $value, $params) { /** * Register comments as a custom search type. * - * @param unknown_type $hook - * @param unknown_type $type - * @param unknown_type $value - * @param unknown_type $params - * @return unknown_type + * @param string $hook Hook name + * @param string $type Hook type + * @param array $value Array of custom search types + * @param array $params Search parameters + * @return array */ function search_custom_types_comments_hook($hook, $type, $value, $params) { $value[] = 'comments'; diff --git a/views/default/css/admin.php b/views/default/css/admin.php index ceeac71a2..8197f29de 100644 --- a/views/default/css/admin.php +++ b/views/default/css/admin.php @@ -1003,7 +1003,7 @@ a.elgg-button { ENTITY MENU *************************************** */ <?php // height depends on line height/font size ?> -.elgg-menu-entity, elgg-menu-annotation { +.elgg-menu-entity, .elgg-menu-annotation { float: right; margin-left: 15px; font-size: 90%; diff --git a/views/default/css/elements/navigation.php b/views/default/css/elements/navigation.php index 49e36e494..6b29e4c19 100644 --- a/views/default/css/elements/navigation.php +++ b/views/default/css/elements/navigation.php @@ -450,7 +450,7 @@ ENTITY AND ANNOTATION *************************************** */ <?php // height depends on line height/font size ?> -.elgg-menu-entity, elgg-menu-annotation { +.elgg-menu-entity, .elgg-menu-annotation { float: right; margin-left: 15px; font-size: 90%; diff --git a/views/default/output/access.php b/views/default/output/access.php index 91c5c721e..5c8d62c4d 100644 --- a/views/default/output/access.php +++ b/views/default/output/access.php @@ -11,7 +11,7 @@ if (isset($vars['entity']) && elgg_instanceof($vars['entity'])) { $access_id = $vars['entity']->access_id; $access_class = 'elgg-access'; $access_id_string = get_readable_access_level($access_id); - $access_id_string = htmlentities($access_id_string, ENT_QUOTES, 'UTF-8'); + $access_id_string = htmlspecialchars($access_id_string, ENT_QUOTES, 'UTF-8', false); // if within a group or shared access collection display group name and open/closed membership status // @todo have a better way to do this instead of checking against subtype / class. |