User search only allows you to search for users names. It would be really awesome if it allowed us to use keywords to search for information users entered in their profiles.

CommentFileSizeAuthor
#11 profile_01.patch2 KBsanduhrs

Comments

pietro’s picture

Component: search.module » profile.module

re-assinging to profile.module since in order to get this done ones needs to implement hook_search in profile.module.

a simple implementation foloows:


function profile_search($op = 'search', $keys = null) {
  switch ($op) {
   case 'name':
      if (user_access('access user profiles')) {
        return t('user profiles');
      }
    case 'search':
      if (user_access('access user profiles')) {
        $find = array();
        // Replace wildcards with MySQL/PostgreSQL wildcards.
        $keys = preg_replace('!\*+!', '%', $keys);
        $result = pager_query("SELECT {profile_values}.*,{users}.name,{users}.uid FROM {profile_values},{users} WHERE LOWER({profile_values}.value) LIKE LOWER('%%%s%%') AND {users}.uid = {profile_values}.uid", 15, 0, NULL, $keys);
        while ($account = db_fetch_object($result)) {
          $find[] = array('title' => $account->name, 'link' => url('user/'. $account->uid));
        }
        return $find;
      }
  }
}
dublin drupaller’s picture

nice one pietro..

how do you apply that? do you just replace/insert the entire profile_search functio in the profile module?

Dub

kbahey’s picture

Hi Dub

You just copy that function to profile.module, there isn't any existing one.

I did that, and it does work. Nice work Pietro.

However, it needs more features, for example, and AND / OR on multiple fields (e.g. Country = Canada AND industry = IT)

Nice start though.

kbahey’s picture

Status: Active » Needs work

Related discussion http://drupal.org/node/32382

kbahey’s picture

Ignore that link above. Here is the correct link http://drupal.org/node/8407

scd67’s picture

Title: Make users profiles searchable » Group by

If you add 'GROUP BY {users}.uid' at the end of the sql statement, you can trip the result set down to only listing a username once, even if they have the term in their profile multiple times.

asimmonds’s picture

Title: Group by » Make users profiles searchable

Don't change the title, it changes for the whole thread

ahoeben’s picture

Would it be possible to have the result of the search operation be more like the result of profile_browse()?

Thinking out loud: how hard does the _search hook break if it doesn't get an array of [title, link]

ahoeben’s picture

This adds the public fields of the profiles to the search results:

function profile_search($op = 'search', $keys = null) {
  switch ($op) {
   case 'name':
      if (user_access('access user profiles')) {
        return t('user profiles');
      }
    case 'search':
      if (user_access('access user profiles')) {
		// Compile a list of fields to show
		$fields = array();
		$result = db_query('SELECT name, title, type, weight FROM {profile_fields} visibility = %d ORDER BY weight', PROFILE_PUBLIC_LISTINGS);
		while ($record = db_fetch_object($result)) {
		  $fields[] = $record;
		}
		
		$find = array();
        // Replace wildcards with MySQL/PostgreSQL wildcards.
        $keys = preg_replace('!\*+!', '%', $keys);
        $result = pager_query("SELECT {profile_values}.*,{users}.name,{users}.uid FROM {profile_values},{users} WHERE LOWER({profile_values}.value) LIKE LOWER('%%%s%%') AND {users}.uid = {profile_values}.uid GROUP BY {users}.uid", 15, 0, NULL, $keys);

		while ($account = db_fetch_object($result)) {
		  $account = user_load(array('uid' => $account->uid));
		  $fields = _profile_update_user_fields($fields, $account);

		  $find[] = array('title' => $account->name, 'snippet' =>theme('profile_listing', $account, $fields), 'link' => url('user/'. $account->uid));
        }
        return $find;
      }
  }
}

Two three caveats:

  • Since hook search insists on having a result array with title and link, the user name is duplicated, which is confusing
  • Formatting is slightly different than the normal profile_browse output; there a dl around each item, and no element with id="profile". May be solved with styling/theming
  • This is not a patch, sorry
smilodon’s picture

...
Will this work with trip_search module as well ???
The default search module is not enought for me, so i use trip_search.

sanduhrs’s picture

Version: 4.6.3 » 4.7.0-beta4
StatusFileSize
new2 KB

in reply to #9.
There was a typo in the first SQL Statment, throwing errors at me.
Nonetheless, thanks a lot, this is exactly what I needed.
A patch against Drupal4.7beta4 is attached.

robertdouglass’s picture

tracking.

JohnG-1’s picture

I too would be interested in getting this to work with trip_search and 4.6.5

Tobias Maier’s picture

Version: 4.7.0-beta4 » x.y.z

1. tracking
2. version...

dobson’s picture

I have modified my profile.module to include checkboxes as a field type (http://drupal.org/node/47744). The checkboxes are stored in the database as a string:

s:LEN:"KEY";s:LEN:"VAL";

where 'VAL' == 'KEY' if option is selected. I think that's just how PHP packs the checkboxes array returned from the form. So my SQL becomes something horrific, although it works well enough so far (no users yet :) To select all profiles which have selected the checkbox option 'fast cars' or 'green people', I do this:

(I am interested in your thoughts on HOW bad this will suck with thirty fields being searched over thousands of users...)

SELECT u.* FROM users u
INNER JOIN profile_values pv ON u.uid = pv.uid
INNER JOIN profile_fields pf ON pv.fid = pf.fid
WHERE
LOWER(pv.value) like LOWER('%Fast Cars%Fast Cars%') OR
LOWER(pv.value) like LOWER('%Green People%Green People%');

I need to do some age discrimination now (eg users from 25-34 yrs old). I guess there are two ways to do this:

1) If I modify the SQL to do something intelligent using min and max values set in search form?

2) If I add a field to the user form and it is not handled by some module before user module saves the user, then it is written to 'data' field in the user table. Is it possible to have it written to a user table field?

I guess this is an SQL question then. :(

Steven’s picture

Status: Needs work » Closed (duplicate)

dobson: please open a forum topic or separate issue for this.

There is another issue with a patch at: http://drupal.org/node/28325 .

robert castelo’s picture

Ooops, didn't see anyone was working on this, so I just coded my own version:

http://drupal.org/node/58788

Now working on how results are displayed - options for display order and concatenating fields and adding new labels:

e.g.

Name: John Smith

Instead of

First Name: John
Last Name: smith

Joeluvnyc’s picture

Version: x.y.z » 6.11

i am on a PC. where do i go to implement this php code to make the user profiles searchable?

thank you for any help.

Joeluvnyc’s picture

Where in profile.module do i place your code? and can i use any text editor to make the change?

thank you