]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Merged r6534-6559 from 1.7 branch to trunk
authorcash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Sat, 21 Aug 2010 20:51:26 +0000 (20:51 +0000)
committercash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Sat, 21 Aug 2010 20:51:26 +0000 (20:51 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@6840 36083f99-b078-4883-b0ff-0f9b5a30f544

19 files changed:
CODING.txt
INSTALL.txt
engine/lib/elgglib.php
engine/lib/metadata.php
engine/lib/output.php
engine/lib/relationships.php
engine/lib/upgrades/2010062301.php [new file with mode: 0644]
engine/lib/upgrades/2010062302.php [new file with mode: 0644]
engine/schema/mysql.sql
engine/schema/upgrades/2010062401.sql [new file with mode: 0644]
engine/tests/api/entity_getter_functions.php
mod/groups/languages/en.php
mod/groups/start.php
mod/groups/views/default/groups/grouplisting.php
mod/search/search_hooks.php
mod/search/start.php
version.php
views/default/friends/picker.php
views/default/input/checkboxes.php

index b2224627f5e0ff5632283361d050dc0bee0faa19..3399d8e2f43ae5879600bfe60d1940094590878e 100644 (file)
@@ -3,11 +3,15 @@
 These are the coding standards for Elgg.  All core development, bundled 
 plugins, and tickets attached to Trac are expected to be in this format.
 
-* Unix line endings
+* Unix line endings.
+
 * Hard tabs, 4 character tab spacing.
-* No PHP shortcut tags ( <? or <?= or <% )
+
+* No PHP shortcut tags ( <? or <?= or <% ).
+
 * PHPDoc comments on functions and classes (all methods; declared properties
   when appropriate).
+
 * Mandatory wrapped {}s around any code blocks. 
        Bad:
        if (true) 
@@ -20,22 +24,32 @@ plugins, and tickets attached to Trac are expected to be in this format.
                        echo $elem;
                }
        }
+
 * Name standalone functions using underscore_character().
+
 * Name classes using CamelCase() and methods using lowerCamelCase().
-* Name globals and constants in ALL_CAPS (FALSE, TRUE, NULL, ACCESS_FRIENDS, 
-  $CONFIG).
-* Space functions like_this($required, $optional = TRUE)
-* Space keywords and constructs like this: if (FALSE) { ... }
+
+* Name globals and constants in ALL_CAPS (TRUE, NULL, ACCESS_FRIENDS, $CONFIG).
+
+* Use underscores / camel case to separate standard English words in
+  functions, classes, and methods. (get_default_site(), ElggUser->isLoggedIn()).
+
+* Space functions like_this($required, $optional = TRUE).
+
+* Space keywords and constructs like this: if (FALSE) { ... }.
+
 * Correctly use spaces, quotes, and {}s in strings: 
        Bad (hard to read, misuse of quotes and {}s): 
        echo 'Hello, '.$name."!  How is your {$time_of_day}?";
        
        Good:
        echo "Hello, $name!  How is your $time_of_day?"; 
-       
+
 * Line lengths should be reasonable.  If you are writing lines over 100 
   characters on a line, please revise the code.
+
 * Use // or /* */ when commenting.
+
 * No closing PHP tag (?>) at EOF unless after a heredoc. (Avoids problems with 
   trailing whitespace. Required after heredoc by PHP.)
 
@@ -51,18 +65,25 @@ work for developers, which means happier, more productive developers.
   If you find a block of code that you want to use multiple times, make a 
   function.  If you find views that are identical except for a single value,
   pull it out into a generic view that takes an option.
+
 * Whitespace is free.  Don't be afraid to use it to separate blocks of code. 
   Use a single space to separate function params and string concatenation.
+
 * Use self-documenting variable names.  $group_guids is better than $array.
+
 * Functions returning an array should return an empty array instead of FALSE
   on no results.
-* FALSE should be returned by functions on failure or error if not throwing an 
-  exception. 
+
+* Functions not throwing an exception on error should return FALSE upon 
+  failure. 
+
 * Functions returning only boolean should be prefaced with is_ or has_ (eg,
   is_logged_in(), has_access_to_entity()).
+
 * Ternary syntax is acceptable for single-line, non-embedded statements.
+
 * Use comments effectively.  Good comments describe the "why."  Good code
-  describes the "how." Ex:
+  describes the "how."  Ex:
        Not a very useful comment:
 
        // increment $i only when the entity is marked as active.
@@ -80,13 +101,14 @@ work for developers, which means happier, more productive developers.
                        $i++;
                }
        }
+
 * Use commit messages effectively.  Be concise and meaningful. Ex:
        Not meaningful:
        Small fix to groups.
 
        Meaningful:
-       Fixes #1234: Missing ) was causing WSOD on group profile page when
-       logged out.
+       Fixes #1234: Added missing ) that caused a WSOD on group profile page
+       when logged out.
 
 * Commit effectively: Err on the side of atomic commits.  One revision with
   many changes is scary.
@@ -101,24 +123,30 @@ indefinitely as plugin authors are expected to properly update their
 plugins.  In order to maintain backward compatibility, deprecated APIs will
 follow these guidelines:
 
-* API changes cannot occur between bugfix versions (1.6.0 - 1.6.1).
+* Incompatible API changes cannot occur between bugfix versions 
+  (1.6.0 - 1.6.1).
+
 * API changes between minor versions (1.6 - 1.7) must maintain backward
   compatibility for at least 2 minor versions.  (1.7 and 1.8. See 
   procedures, below.)
+
 * Bugfixes that change the API cannot be included in bugfix versions.
+
 * API changes between major versions (1.0 - 2.0) can occur without regard to
   backward compatibility.
 
-The procedures for deprecating an API are as follows:
+The procedure for deprecating an API is as follows:
 
 * The first minor version (1.7) with a deprecated API must include a wrapper
   function/class (or otherwise appropriate means) to maintain backward
   compatibility, including any bugs in the original function/class.
-  This wrapper function will elgg_deprecated_notice('...', 1.7) to log
+  This compatibility layer uses elgg_deprecated_notice('...', 1.7) to log
   that the function is deprecated.
+
 * The second minor version (1.8) maintains the backward compatibility
-  wrapper, but elgg_deprecated_notice() will produce a visible warning.
-* The third minor version (1.9) removes the wrapper function.  Any use of 
+  layer, but elgg_deprecated_notice() will produce a visible warning.
+
+* The third minor version (1.9) removes the compatibility layer.  Any use of 
   the deprecated API should be corrected before this.
 
 The general timeline for two minor releases is 8 to 12 months.
index 20007fad785014597463b4a65e3d830da2ac03ed..33aa2370829779848794447a7ae9275c67342e67 100644 (file)
@@ -66,7 +66,7 @@ Once this folder has been created, you'll need to make sure that your
 web server has permission to write to it. This shouldn't be a problem 
 on Windows-based servers, but if your server runs Linux or a UNIX variant, 
 you'll need to figure out what user Apache runs under. For Debian-based 
-distros, it is usually www-data and for RedHat, it is often apache. If 
+distros, it is usually www-data and for RedHat, it is often apache. If you
 cannot figure out what the ownership and permissions should be, you can
 set the permissions for world access (though not recommended):
 
index f74fbec094267b8d47c256e5139f596496f0b44a..3d08227e4e0a07f52a4b9768a6b869f615129541 100644 (file)
@@ -1624,22 +1624,15 @@ function is_not_null($string) {
 function elgg_normalise_plural_options_array($options, $singulars) {
        foreach ($singulars as $singular) {
                $plural = $singular . 's';
-
-               // normalize the singular to plural
-               // isset() returns FALSE for array values of NULL, so they are ignored.
-               // everything else falsy is included.
-               //if (isset($options[$singular]) && $options[$singular] !== NULL && $options[$singular] !== FALSE) {
-               if (isset($options[$singular])) {
-                       if (isset($options[$plural])) {
-                               if (is_array($options[$plural])) {
-                                       $options[$plural][] = $options[$singlar];
-                               } else {
-                                       $options[$plural] = array($options[$plural], $options[$singular]);
-                               }
+               
+               if (array_key_exists($singular, $options)) {
+                       if ($options[$singular] === ELGG_ENTITIES_ANY_VALUE) {
+                               $options[$plural] = $options[$singular];
                        } else {
                                $options[$plural] = array($options[$singular]);
                        }
                }
+                
                unset($options[$singular]);
        }
 
index 74ea6858a653024aa7f1c4d392a4902c8daa2991..6e849cdd9f4ac527e3889c575e7bab356894c62b 100644 (file)
@@ -186,10 +186,11 @@ function remove_metadata($entity_guid, $name, $value = "") {
  * @param int $entity_guid The entity to attach the metadata to
  * @param string $name Name of the metadata
  * @param string $value Value of the metadata (cannot be associative array)
- * @param string $value_type
- * @param int $owner_guid
- * @param int $access_id
- * @param bool $allow_multiple
+ * @param string $value_type 'text', 'integer', or '' for automatic detection
+ * @param int $owner_guid GUID of entity that owns the metadata
+ * @param int $access_id Default is ACCESS_PRIVATE
+ * @param bool $allow_multiple Allow multiple values for one key. Default is FALSE
+ * @return bool
  */
 function create_metadata($entity_guid, $name, $value, $value_type, $owner_guid, $access_id = ACCESS_PRIVATE, $allow_multiple = false) {
        global $CONFIG;
@@ -218,8 +219,7 @@ function create_metadata($entity_guid, $name, $value, $value_type, $owner_guid,
                if (!$result) {
                        return false;
                }
-       }
-       else if (isset($value)) {
+       } else if (isset($value)) {
                // Support boolean types
                if (is_bool($value)) {
                        if ($value) {
@@ -343,12 +343,12 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i
 /**
  * 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
+ * @param int $entity_guid The entity to attach the metadata to
+ * @param string $name_and_values Associative array
+ * @param string $value_type 'text', 'integer', or '' for automatic detection
+ * @param int $owner_guid GUID of entity that owns the metadata
+ * @param int $access_id Default is ACCESS_PRIVATE
+ * @param bool $allow_multiple Allow multiple values for one key. Default is FALSE
  */
 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) {
index 70c3821d6e0bc79c2cedf441c2e32aa97905bcfb..3b82447b0e263e178cbc9bc9d60271fec8e5bfc7 100644 (file)
@@ -116,7 +116,7 @@ function elgg_make_excerpt($text, $num_chars = 250) {
        $excerpt = trim(elgg_substr($excerpt, 0, $space));
 
        if ($string_length != elgg_strlen($excerpt)) {
-               $excerpt .= '&#8230';
+               $excerpt .= '...';
        }
 
        return $excerpt;
index f813cacbadf401d0ee31b4f3de07e050956eff7f..f1d119452a7b42f11ee2c39af1b1412be18d2eb1 100644 (file)
@@ -358,13 +358,16 @@ function add_entity_relationship($guid_one, $relationship, $guid_two) {
        $guid_one = (int)$guid_one;
        $relationship = sanitise_string($relationship);
        $guid_two = (int)$guid_two;
+       $time = time();
 
        // 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)");
+       $result = insert_data("INSERT into {$CONFIG->dbprefix}entity_relationships 
+               (guid_one, relationship, guid_two, time_created)
+               values ($guid_one, '$relationship', $guid_two, $time)");
 
        if ($result!==false) {
                $obj = get_relationship($result);
diff --git a/engine/lib/upgrades/2010062301.php b/engine/lib/upgrades/2010062301.php
new file mode 100644 (file)
index 0000000..96fd6c8
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * Change ownership of group ACLs to group entity
+ */
+
+elgg_set_ignore_access(TRUE);
+
+$params = array('type' => 'group',
+                               'limit' => 0);
+$groups = elgg_get_entities($params);
+if ($groups) {
+       foreach ($groups as $group) {
+               $acl = $group->group_acl;
+
+               $query = "UPDATE {$CONFIG->dbprefix}access_collections SET owner_guid = $group->guid WHERE id = $acl";
+               update_data($query);
+       }
+}
+elgg_set_ignore_access(FALSE);
+
diff --git a/engine/lib/upgrades/2010062302.php b/engine/lib/upgrades/2010062302.php
new file mode 100644 (file)
index 0000000..fe33e12
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * Make sure that everyone who belongs to a group is a member of the group's access collection
+ */
+
+
+elgg_set_ignore_access(TRUE);
+
+$params = array('type' => 'group', 'limit' => 0);
+$groups = elgg_get_entities($params);
+if ($groups) {
+       foreach ($groups as $group) {
+               $acl = $group->group_acl;
+
+               $query = "SELECT u.guid FROM {$CONFIG->dbprefix}users_entity u
+                       JOIN {$CONFIG->dbprefix}entity_relationships r
+                               ON u.guid = r.guid_one AND r.relationship = 'member' AND r.guid_two = $group->guid
+                       LEFT JOIN {$CONFIG->dbprefix}access_collection_membership a
+                               ON u.guid = a.user_guid AND a.access_collection_id = $acl
+                               WHERE a.user_guid IS NULL";
+
+               $results = get_data($query);
+               if ($results != FALSE) {
+                       foreach ($results as $user) {
+                               $insert = "INSERT INTO {$CONFIG->dbprefix}access_collection_membership
+                                                       (user_guid, access_collection_id) VALUES ($user->guid, $acl)";
+                               insert_data($insert);
+                       }
+               }
+       }
+}
+elgg_set_ignore_access(FALSE);
index 23e81f39de1a28d694471cdb2485d8a52a1a6f69..526cc8ce6cda69c0b2589b9cf2f4959f1170809d 100644 (file)
@@ -155,6 +155,7 @@ CREATE TABLE `prefix_entity_relationships` (
   `guid_one` bigint(20) unsigned NOT NULL,
   `relationship` varchar(50) NOT NULL,
   `guid_two` bigint(20) unsigned NOT NULL,
+  `time_created` int(11) NOT NULL,
   PRIMARY KEY (`id`),
   UNIQUE KEY `guid_one` (`guid_one`,`relationship`,`guid_two`),
   KEY `relationship` (`relationship`),
diff --git a/engine/schema/upgrades/2010062401.sql b/engine/schema/upgrades/2010062401.sql
new file mode 100644 (file)
index 0000000..fbb49bf
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE `prefix_entity_relationships` ADD COLUMN `time_created` int(11) NOT NULL AFTER `guid_two`;
\ No newline at end of file
index faa91db3457665e43caf71265b3f3ef365a2039d..f193fda415658af3b0d62688bfe671941d674c55 100644 (file)
@@ -2168,7 +2168,7 @@ class ElggCoreEntityGetterFunctionsTest extends ElggCoreUnitTest {
                );
                
                $es = elgg_get_entities_from_relationship($options);
-               
+
                $this->assertTrue(empty($es));
 
                foreach ($guids as $guid) {
@@ -2176,4 +2176,191 @@ class ElggCoreEntityGetterFunctionsTest extends ElggCoreUnitTest {
                        $e->delete();
                }
        }
+       
+       public function testElggApiGettersEntitySiteSingular() {
+               global $CONFIG;
+               
+               $guids = array();
+               
+               $obj1 = new ElggObject();
+               $obj1->test_md = 'test';
+               // luckily this is never checked.
+               $obj1->site_guid = 2;
+               $obj1->save();
+               $guids[] = $obj1->guid;
+               $right_guid = $obj1->guid;
+
+               $obj2 = new ElggObject();
+               $obj2->test_md = 'test';
+               $obj2->site_guid = $CONFIG->site->guid;
+               $obj2->save();
+               $guids[] = $obj2->guid;
+               
+               $options = array(
+                       'metadata_name' => 'test_md',
+                       'metadata_value' => 'test',
+                       'site_guid' => 2
+               );
+               
+               $es = elgg_get_entities_from_metadata($options);
+               $this->assertTrue(is_array($es));
+               $this->assertEqual(1, count($es));
+               $this->assertEqual($right_guid, $es[0]->guid);
+               
+               foreach ($guids as $guid) {
+                       get_entity($guid)->delete();
+               }
+       }
+       
+       public function testElggApiGettersEntitySiteSingularAny() {
+               global $CONFIG;
+               
+               $guids = array();
+               
+               $obj1 = new ElggObject();
+               $obj1->test_md = 'test';
+               // luckily this is never checked.
+               $obj1->site_guid = 2;
+               $obj1->save();
+               $guids[] = $obj1->guid;
+
+               $obj2 = new ElggObject();
+               $obj2->test_md = 'test';
+               $obj2->site_guid = $CONFIG->site->guid;
+               $obj2->save();
+               $guids[] = $obj2->guid;
+               
+               $options = array(
+                       'metadata_name' => 'test_md',
+                       'metadata_value' => 'test',
+                       'site_guid' => ELGG_ENTITIES_ANY_VALUE,
+                       'limit' => 2,
+                       'order_by' => 'e.guid DESC'
+               );
+               
+               $es = elgg_get_entities_from_metadata($options);
+               $this->assertTrue(is_array($es));
+               $this->assertEqual(2, count($es));
+               
+               foreach ($es as $e) {
+                       $this->assertTrue(in_array($e->guid, $guids));
+               }
+               
+               foreach ($guids as $guid) {
+                       get_entity($guid)->delete();
+               }
+       }
+       
+       public function testElggApiGettersEntitySitePlural() {
+               global $CONFIG;
+               
+               $guids = array();
+               
+               $obj1 = new ElggObject();
+               $obj1->test_md = 'test';
+               // luckily this is never checked.
+               $obj1->site_guid = 2;
+               $obj1->save();
+               $guids[] = $obj1->guid;
+
+               $obj2 = new ElggObject();
+               $obj2->test_md = 'test';
+               $obj2->site_guid = $CONFIG->site->guid;
+               $obj2->save();
+               $guids[] = $obj2->guid;
+               
+               $options = array(
+                       'metadata_name' => 'test_md',
+                       'metadata_value' => 'test',
+                       'site_guids' => array($CONFIG->site->guid, 2),
+                       'limit' => 2,
+                       'order_by' => 'e.guid DESC'
+               );
+               
+               $es = elgg_get_entities_from_metadata($options);
+               $this->assertTrue(is_array($es));
+               $this->assertEqual(2, count($es));
+               
+               foreach ($es as $e) {
+                       $this->assertTrue(in_array($e->guid, $guids));
+               }
+               
+               foreach ($guids as $guid) {
+                       get_entity($guid)->delete();
+               }
+       }
+       
+       public function testElggApiGettersEntitySitePluralSomeInvalid() {
+               global $CONFIG;
+               
+               $guids = array();
+               
+               $obj1 = new ElggObject();
+               $obj1->test_md = 'test';
+               // luckily this is never checked.
+               $obj1->site_guid = 2;
+               $obj1->save();
+               $guids[] = $obj1->guid;
+
+               $obj2 = new ElggObject();
+               $obj2->test_md = 'test';
+               $obj2->save();
+               $guids[] = $obj2->guid;
+               $right_guid = $obj2->guid;
+               
+               $options = array(
+                       'metadata_name' => 'test_md',
+                       'metadata_value' => 'test',
+                       // just created the first entity so nothing will be "sited" by it.
+                       'site_guids' => array($CONFIG->site->guid, $guids[0]),
+                       'limit' => 2,
+                       'order_by' => 'e.guid DESC'
+               );
+               
+               $es = elgg_get_entities_from_metadata($options);
+               
+               $this->assertTrue(is_array($es));
+               $this->assertEqual(1, count($es));
+               $this->assertEqual($es[0]->guid, $right_guid);
+               
+               foreach ($guids as $guid) {
+                       get_entity($guid)->delete();
+               }
+       }
+       
+       public function testElggApiGettersEntitySitePluralAllInvalid() {
+               global $CONFIG;
+               
+               $guids = array();
+               
+               $obj1 = new ElggObject();
+               $obj1->test_md = 'test';
+               // luckily this is never checked.
+               $obj1->site_guid = 2;
+               $obj1->save();
+               $guids[] = $obj1->guid;
+
+               $obj2 = new ElggObject();
+               $obj2->test_md = 'test';
+               $obj2->save();
+               $guids[] = $obj2->guid;
+               $right_guid = $obj2->guid;
+               
+               $options = array(
+                       'metadata_name' => 'test_md',
+                       'metadata_value' => 'test',
+                       // just created the first entity so nothing will be "sited" by it.
+                       'site_guids' => array($guids[0], $guids[1]),
+                       'limit' => 2,
+                       'order_by' => 'e.guid DESC'
+               );
+               
+               $es = elgg_get_entities_from_metadata($options);
+               
+               $this->assertTrue(empty($es));
+               
+               foreach ($guids as $guid) {
+                       get_entity($guid)->delete();
+               }
+       }
 }
index 58a6c7f3153e9aa254136add2abcb9f61a2d94e4..7ecd00f57477527f566254f07ef6af2adbc9989d 100644 (file)
@@ -133,7 +133,7 @@ $english = array(
        'grouptopic:error' => 'Your group topic could not be created. Please try again or contact a system administrator.',
        'groups:forumpost:edited' => "You have successfully edited the forum post.",
        'groups:forumpost:error' => "There was a problem editing the forum post.",
-       'groups:privategroup' => 'This group is private, requesting membership.',
+       'groups:privategroup' => 'This group is closed. Requesting membership.',
        'groups:notitle' => 'Groups must have a title',
        'groups:cantjoin' => 'Can not join group',
        'groups:cantleave' => 'Could not leave group',
index 3278b66829738b24a93ef5a49da3a7b8607a5d90..215311ef97961a70975c3c395423fc9c35945638 100644 (file)
        }
 
        /**
-        * Groups created, so add users to access lists.
+        * Groups created so create an access list for it
         */
        function groups_create_event_listener($event, $object_type, $object)
        {
-               //if (($event == 'create') && ($object_type == 'group') && ($object instanceof ElggGroup))
-               //{
-                       $group_id = create_access_collection(elgg_echo('groups:group') . ": " . $object->name);
-                       if ($group_id)
-                       {
-                               $object->group_acl = $group_id;
-                       }
-                       else
-                               return false;
-               //}
+               $ac_name = elgg_echo('groups:group') . ": " . $object->name;
+               $group_id = create_access_collection($ac_name, $object->guid);
+               if ($group_id) {
+                       $object->group_acl = $group_id;
+               } else {
+                       // delete group if access creation fails
+                       return false;
+               }
 
                return true;
        }
                add_user_to_access_collection($user->guid, $acl);
 
                return true;
-
        }
 
        /**
                remove_user_from_access_collection($user->guid, $acl);
 
                return true;
-
        }
 
        /**
index 48a7b1ace26b03d64e71857e83944f1da286b8da..687aebfa0860802135b98107957096da636b6b68 100644 (file)
@@ -19,7 +19,7 @@ $icon = elgg_view(
 
 //get the membership type
 $membership = $vars['entity']->membership;
-if($membership == 2) {
+if($membership == ACCESS_PUBLIC) {
        $mem = elgg_echo("groups:open");
 } else {
        $mem = elgg_echo("groups:closed");
index 86a6b452f5d356de2d2fde2ef8bdbeaa5e66fe12..516bb2098941ff498bf9b403efe4ba159d345a0d 100644 (file)
@@ -24,18 +24,19 @@ function search_objects_hook($hook, $type, $value, $params) {
        $params['joins'] = array($join);
        $fields = array('title', 'description');
 
-       $where = search_get_where_sql('oe', $fields, $params);
+       $where = search_get_where_sql('oe', $fields, $params, FALSE);
 
        $params['wheres'] = array($where);
-
-       $entities = elgg_get_entities($params);
        $params['count'] = TRUE;
        $count = elgg_get_entities($params);
-
+       
        // no need to continue if nothing here.
        if (!$count) {
                return array('entities' => array(), 'count' => $count);
        }
+       
+       $params['count'] = FALSE;
+       $entities = elgg_get_entities($params);
 
        // add the volatile data for why these entities have been returned.
        foreach ($entities as $entity) {
@@ -68,25 +69,28 @@ function search_groups_hook($hook, $type, $value, $params) {
 
        $join = "JOIN {$CONFIG->dbprefix}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 = "(ge.guid = e.guid
-               AND (ge.name LIKE '%$query%'
-                       OR ge.description LIKE '%$query%'
-                       )
-               )";
        $params['wheres'] = array($where);
 
        // override subtype -- All groups should be returned regardless of subtype.
        $params['subtype'] = ELGG_ENTITIES_ANY_VALUE;
 
-       $entities = elgg_get_entities($params);
        $params['count'] = TRUE;
        $count = elgg_get_entities($params);
-
+       
        // no need to continue if nothing here.
        if (!$count) {
                return array('entities' => array(), 'count' => $count);
        }
+       
+       $params['count'] = FALSE;
+       $entities = elgg_get_entities($params);
 
        // add the volatile data for why these entities have been returned.
        foreach ($entities as $entity) {
@@ -122,17 +126,20 @@ function search_users_hook($hook, $type, $value, $params) {
        $join = "JOIN {$CONFIG->dbprefix}users_entity ue ON e.guid = ue.guid";
        $params['joins'] = array($join);
 
-       $where = "(ue.guid = e.guid
-               AND (ue.username LIKE '%$query%'
-                       OR ue.name LIKE '%$query%'
-                       )
-               )";
+//     $where = "(ue.guid = e.guid
+//             AND (ue.username LIKE '%$query%'
+//                     OR ue.name LIKE '%$query%'
+//                     )
+//             )";
+
+       $fields = array('username', 'name');
+       $where = search_get_where_sql('ue', $fields, $params, FALSE);
+       
        $params['wheres'] = array($where);
 
        // override subtype -- All users should be returned regardless of subtype.
        $params['subtype'] = ELGG_ENTITIES_ANY_VALUE;
 
-       $entities = elgg_get_entities($params);
        $params['count'] = TRUE;
        $count = elgg_get_entities($params);
 
@@ -140,6 +147,9 @@ function search_users_hook($hook, $type, $value, $params) {
        if (!$count) {
                return array('entities' => array(), 'count' => $count);
        }
+       
+       $params['count'] = FALSE;
+       $entities = elgg_get_entities($params);
 
        // add the volatile data for why these entities have been returned.
        foreach ($entities as $entity) {
@@ -212,7 +222,6 @@ function search_tags_hook($hook, $type, $value, $params) {
 
        $params['wheres'][] = "(msn.string IN ($tags_in) AND msv.string = '$query' AND $access)";
 
-       $entities = elgg_get_entities($params);
        $params['count'] = TRUE;
        $count = elgg_get_entities($params);
 
@@ -220,6 +229,9 @@ function search_tags_hook($hook, $type, $value, $params) {
        if (!$count) {
                return array('entities' => array(), 'count' => $count);
        }
+       
+       $params['count'] = FALSE;
+       $entities = elgg_get_entities($params);
 
        // add the volatile data for why these entities have been returned.
        foreach ($entities as $entity) {
@@ -332,7 +344,7 @@ function search_comments_hook($hook, $type, $value, $params) {
        $e_access = get_access_sql_suffix('e');
        $a_access = get_access_sql_suffix('a');
        // @todo this can probably be done through the api..
-       $q = "SELECT DISTINCT a.*, msv.string as comment FROM {$CONFIG->dbprefix}annotations a
+       $q = "SELECT count(DISTINCT a.id) as total FROM {$CONFIG->dbprefix}annotations a
                JOIN {$CONFIG->dbprefix}metastrings msn ON a.name_id = msn.id
                JOIN {$CONFIG->dbprefix}metastrings msv ON a.value_id = msv.id
                JOIN {$CONFIG->dbprefix}entities e ON a.entity_guid = e.guid
@@ -341,13 +353,20 @@ function search_comments_hook($hook, $type, $value, $params) {
                        AND $e_access
                        AND $a_access
                        $container_and
-
-               LIMIT {$params['offset']}, {$params['limit']}
                ";
 
-       $comments = get_data($q);
-
-       $q = "SELECT count(DISTINCT a.id) as total FROM {$CONFIG->dbprefix}annotations a
+       if (!$result = get_data($q)) {
+               return FALSE;
+       }
+       
+       $count = $result[0]->total;
+       
+       // don't continue if nothing there...
+       if (!$count) {
+               return array ('entities' => array(), 'count' => 0);
+       }
+       
+       $q = "SELECT DISTINCT a.*, msv.string as comment FROM {$CONFIG->dbprefix}annotations a
                JOIN {$CONFIG->dbprefix}metastrings msn ON a.name_id = msn.id
                JOIN {$CONFIG->dbprefix}metastrings msv ON a.value_id = msv.id
                JOIN {$CONFIG->dbprefix}entities e ON a.entity_guid = e.guid
@@ -356,14 +375,11 @@ function search_comments_hook($hook, $type, $value, $params) {
                        AND $e_access
                        AND $a_access
                        $container_and
-               ";
 
-       $result = get_data($q);
-       $count = $result[0]->total;
+               LIMIT {$params['offset']}, {$params['limit']}
+               ";
 
-       if (!is_array($comments)) {
-               return FALSE;
-       }
+       $comments = get_data($q);
 
        // @todo if plugins are disabled causing subtypes
        // to be invalid and there are comments on entities of those subtypes,
index 781afb8ec2f87e5abcc5516263a706e14766acfc..ae5e71c976851344e466f252357bf4ad4b6be247 100644 (file)
@@ -259,8 +259,12 @@ function search_highlight_words($words, $string) {
        );
 
        foreach ($words as $word) {
+               // remove any boolean mode operators
+               $word = preg_replace("/([\-\+~])([\w]+)/i", '$2', $word);
+               
                // escape the delimiter and any other regexp special chars
                $word = preg_quote($word, '/');
+               
                $search = "/($word)/i";
 
                // must replace with placeholders in case one of the search terms is
@@ -297,7 +301,9 @@ function search_remove_ignored_words($query, $format = 'array') {
        global $CONFIG;
 
        // don't worry about "s or boolean operators
-       $query = str_replace(array('"', '-', '+', '~'), '', stripslashes(strip_tags($query)));
+       //$query = str_replace(array('"', '-', '+', '~'), '', stripslashes(strip_tags($query)));
+       $query = stripslashes(strip_tags($query));
+       
        $words = explode(' ', $query);
 
        $min_chars = $CONFIG->search_info['min_chars'];
@@ -386,12 +392,8 @@ function search_get_where_sql($table, $fields, $params, $use_fulltext = TRUE) {
                        $fields[$i] = "$table.$field";
                }
        }
-
-       // if we're not using full text, rewrite the query for bool mode.
-       // exploiting a feature(ish) of bool mode where +-word is the same as -word
-       if (!$use_fulltext) {
-               $query = '+' . str_replace(' ', ' +', $query);
-       }
+       
+       $where = '';
 
        // if query is shorter than the min for fts words
        // it's likely a single acronym or similar
@@ -405,22 +407,30 @@ function search_get_where_sql($table, $fields, $params, $use_fulltext = TRUE) {
                $likes_str = implode(' OR ', $likes);
                $where = "($likes_str)";
        } else {
-               // if using advanced or paired "s, switch into boolean mode
-               if (!$use_fulltext
-               || (isset($params['advanced_search']) && $params['advanced_search'])
-               || elgg_substr_count($query, '"') >= 2 ) {
+               // if we're not using full text, rewrite the query for bool mode.
+               // exploiting a feature(ish) of bool mode where +-word is the same as -word
+               if (!$use_fulltext) {
+                       $query = '+' . str_replace(' ', ' +', $query);
+               }
+               
+               // if using advanced, boolean operators, or paired "s, switch into boolean mode
+               $booleans_used = preg_match("/([\-\+~])([\w]+)/i", $query);
+               $advanced_search = (isset($params['advanced_search']) && $params['advanced_search']);
+               $quotes_used = (elgg_substr_count($query, '"') >= 2); 
+               
+               if (!$use_fulltext || $booleans_used || $advanced_search || $quotes_used) {
                        $options = 'IN BOOLEAN MODE';
                } else {
                        // natural language mode is default and this keyword isn't supported in < 5.1
                        //$options = 'IN NATURAL LANGUAGE MODE';
                        $options = '';
                }
-
+               
                // if short query, use query expansion.
                // @todo doesn't seem to be working well.
-               if (elgg_strlen($query) < 5) {
-                       //$options .= ' WITH QUERY EXPANSION';
-               }
+//             if (elgg_strlen($query) < 5) {
+//                     $options .= ' WITH QUERY EXPANSION';
+//             }
                $query = sanitise_string($query);
 
                $fields_str = implode(',', $fields);
index 6fc5f8f5049dc1caae254fec35a94761e76774dd..e8dd540f7f9c52f96c0216906e8ac1c736728fdd 100644 (file)
@@ -12,7 +12,7 @@
 
 // YYYYMMDD = Elgg Date
 // XX = Interim incrementer
-$version = 2010061501;
+$version = 2010062401;
 
 // Human-friendly version name
 $release = '1.8-svn';
index 4b8d101118ea1381e9514a789bb4b9347e5b4654..7b47ed67517426b4c985174ac2ba00ed9f7a4050 100644 (file)
@@ -83,6 +83,14 @@ if (is_array($vars['entities']) && sizeof($vars['entities'])) {
        }
 }
 
+// sort users in letters alphabetically
+foreach ($users as $letter => $letter_users) {
+       usort($letter_users, create_function('$a, $b', '
+               return strcasecmp($a->name, $b->name);
+       '));
+       $users[$letter] = $letter_users;
+}
+
 if (!$callback) {
        ?>
 
index fa7c0c34cb6d12f3c401cb92037570090369bfd5..088a97709dd83dea81b0cf3e6d193337bc2c0112 100644 (file)
@@ -2,52 +2,97 @@
 /**
  * Elgg checkbox input
  * Displays a checkbox input field
+ * NB: This also includes a hidden input with the same name as the checkboxes
+ * to make sure something is sent to the server.  The default value is 0.
+ * If using JS, be specific to avoid selecting the hidden default value:
+ *     $('input[type=checkbox][name=internalname])
  *
  * @package Elgg
  * @subpackage Core
  * @author Curverider Ltd
  * @link http://elgg.org/
  *
- * @uses $vars['value'] The current value, if any
- * @uses $vars['js'] Any Javascript to enter into the input tag
- * @uses $vars['internalname'] The name of the input field
- * @uses $vars['options'] An array of strings representing the label => options for the checkbox field
+ * @uses string $vars['internalname'] The name of the input fields (Forced to an array by appending [])
+ * @uses array $vars['options'] An array of strings representing the label => option for the each checkbox field
+ * @uses string $vars['internalid'] The id for each input field. Optional (Only use this with a single value.)
+ * @uses string $vars['default'] The default value to send if nothing is checked. Optional, defaults to 0.
+ * @uses bool $vars['disabled'] Make all input elements disabled. Optional.
+ * @uses string $vars['value'] The current value. Optional.
+ * @uses string $vars['class'] The class of each input element. Optional.
+ * @uses string $vars['js'] Any Javascript to enter into the input tag. Optional.
  *
  */
 
-$class = $vars['class'];
-if (!$class) {
-       $class = "input_checkboxes";
+if (!isset($vars['value']) || $vars['value'] === FALSE) { 
+       $vars['value'] = elgg_get_sticky_value($vars['internalname']); 
 }
 
-if (!isset($vars['value']) || $vars['value'] === FALSE) {
-       $vars['value'] = elgg_get_sticky_value($vars['internalname']);
-}
+$class = (isset($vars['class'])) ? $vars['class'] : 'input_checkboxes';
+$value = (isset($vars['value'])) ? $vars['value'] : NULL;
+$value_array = (is_array($value)) ? array_map('strtolower', $value) : array(strtolower($value));
+$internalname = (isset($vars['internalname'])) ? $vars['internalname'] : '';
+$options = (isset($vars['options']) && is_array($vars['options'])) ? $vars['options'] : array();
+$default = (isset($vars['default'])) ? $vars['default'] : 0;
 
-foreach($vars['options'] as $label => $option) {
-       //if (!in_array($option,$vars['value'])) {
-       if (is_array($vars['value'])) {
-               $valarray = $vars['value'];
-               $valarray = array_map('strtolower', $valarray);
-               if (!in_array(strtolower($option),$valarray)) {
-                       $selected = "";
-               } else {
-                       $selected = "checked = \"checked\"";
+$id = (isset($vars['internalid'])) ? $vars['internalid'] : '';
+$disabled = (isset($vars['disabled'])) ? $vars['disabled'] : FALSE;
+$js = (isset($vars['js'])) ? $vars['js'] : '';
+
+if ($options) {
+       // include a default value so if nothing is checked 0 will be passed.
+       if ($internalname) {
+               echo "<input type=\"hidden\" name=\"$internalname\" value=\"$default\">";
+       }
+
+       foreach($options as $label => $option) {
+               // @hack - This sorta checks if options is not an assoc array and then
+               // ignores the label (because it's just the index) and sets the value ($option)
+               // as the label.
+               // Wow.
+               $labelint = (int) $label;
+
+               if ("{$label}" == "{$labelint}") {
+                       $label = $option;
                }
-       } else {
-               if (strtolower($option) != strtolower($vars['value'])) {
-                       $selected = "";
+
+               if (!in_array(strtolower($option), $value_array)) {
+                       $selected = FALSE;
                } else {
-                       $selected = "checked = \"checked\"";
+                       $selected = TRUE;
+               }
+
+               $attr = array(
+                       'type="checkbox"',
+                       'value="' . htmlentities($option, ENT_QUOTES, 'UTF-8') . '"'
+               );
+
+               if ($id) {
+                       $attr[] = "id=\"$id\"";
                }
-       }
-       $labelint = (int) $label;
-       if ("{$label}" == "{$labelint}") {
-               $label = $option;
-       }
 
-       if (isset($vars['internalid'])) $id = "id=\"{$vars['internalid']}\"";
-       $disabled = "";
-       if ($vars['disabled']) $disabled = ' disabled="yes" ';
-       echo "<label><input type=\"checkbox\" $id $disabled {$vars['js']} name=\"{$vars['internalname']}[]\" value=\"".htmlentities($option, ENT_QUOTES, 'UTF-8')."\" {$selected} class=\"$class\" />{$label}</label><br />";
+               if ($class) {
+                       $attr[] = "class=\"$class\"";
+               }
+
+               if ($disabled) {
+                       $attr[] = 'disabled="yes"';
+               }
+
+               if ($selected) {
+                       $attr[] = 'checked = "checked"';
+               }
+
+               if ($js) {
+                       $attr[] = $js;
+               }
+
+               if ($internalname) {
+                       // @todo this really, really should only add the []s if there are > 1 element in options.
+                       $attr[] = "name=\"{$internalname}[]\"";
+               }
+
+               $attr_str = implode(' ', $attr);
+
+               echo "<label><input $attr_str />$label</label><br />";
+       }
 }
\ No newline at end of file