Having the ability to search profiles beyond just the user name would seem to be a feature that would be incorporated in 5.1.

For example:

If we add a custom profile field so that users can add their country to their profile, why doesn't the Drupal search feature then have the ability to search all user profiles and provide a list of users that reside in the same country?

Is there a modification to search.module that is required to enable a profile search beyond just searching for a user name?

Thanks.

Comments

dldege’s picture

The profileplus module gave a version of this for 4.7. Its pretty simple to upgrade this to 5.0 since it doesn't use many hooks. Mostly just needs a .info file to work with 5.0.

http://drupal.org/project/profileplus

I agree that profile searching should be included in core.

dLd

luger’s picture

I like the simplicity of the module and I added the .info file and installed it in 5.1 without a hitch.

However, when using the "profile search" feature and entering a profile word that exists in a user's profile, I get the infamous "Your search yielded no results" message.

Any ideas on how to tweak the module for 5.1 will be mooooost appreciated.

Thanks again.

Luger

dldege’s picture

I removed the profileplus_menu() function in my version - I don't think that is right or needed in 5.x. You'll need to flush your menu cache after removing that function.

I can send you my customized version (it has an additional features you may or may not want) if you want.

dLd

luger’s picture

Thanks for the generous offer of your customized version.

Did you want to paste it in my Contact Form?

I'm looking forward to it.

Thanks dldege.

Luger

dldege’s picture

http://www.argz.com/~dand/profileplus.zip

Let me know if it works for you...

Once enabled try going to

?q=search/profileplus

Cheers.

dLd

luger’s picture

Hi dldege:

Thanks for providing your module for testing.

These are my observations after installing and testing...

I found that profileplus works for finding profile data if the data was entered from a text or textarea field during user registration.

I did find that I could not search profile data if the data was entered from "select list" boxes during user registration.

I think, and I'm shooting from the hip here, that if users register information during registration from multiple "select list" boxes, the data is serialized i.e. it's entered as one big serialized dump into the "data" field in mySQL for the user, the profile search will not work because (my guess) it seems like it doesn't know how to parse this "serialized dump" in the mySQL "data" field.

It really seems to me that their are probably thousands of Drupal users who could use a full profile search as part of Core.

If you agree or disagree with my findings, or, if you have any suggestions please let me know.

Thanks again.

Luger

dldege’s picture

There is a current bug/feature discussion about how the profile registration data is put into the user table instead of the profile_values table so you are correct in that observation - the data put in at registration is not being searched. This is a bad design/bug IMO. see http://drupal.org/node/119114

As far as the profileplus search goes it only searches public fields (regardless of type such as drop list, text, etc.) that are also marked to show in the profile listings. This is the last option in the profile field configuration. It also skips blocked users and users who have never logged in.

Here is the sql used.

          $sql = "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('%%%s%%') AND pf.visibility IN (%d) AND u.status = 1 AND u.uid != %d";

          $result = pager_query('SELECT DISTINCT u.uid, u.access '.$sql, variable_get('profileplus_results_per_page', 5), 0, 'SELECT COUNT(DISTINCT u.uid) '.$sql, $keys, PROFILE_PUBLIC_LISTINGS, $user->uid);

You can alter this if you want it to be a little less restrictive.

dLd

luger’s picture

substituted the following query for the anonymous user search:

$sql = "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('%%%s%%')";
$result = pager_query('SELECT DISTINCT u.uid, u.access '.$sql, variable_get('profileplus_results_per_page', 5), 0, 'SELECT COUNT(DISTINCT u.uid) '.$sql, $keys);

This allowed me to rule out any possible conflicts with public vs. private data for testing purposes. I still couldn't grab the "drop list" data from the search query.

I guess I'll still play around with it for while to see if I can get it to work. Perhaps I'll create a clean install on my test server and start from scratch.

Thanks again.

Luger

dldege’s picture

If you want to post a link to a test site I'd be happy to take a look.

dLd

globalplayer’s picture

is it possible to create block with profile search? and than show it on selected page in sidebar?

tmj2k7’s picture

First, thanks for the modified module....works well enough for my needs.

As for the blocks, I'm sure you could just make a custom block with a form in it that would utilize the profileplus search URL.

Modern Jurist: A Site For Lawyers

designwork’s picture

Dear Luger,

i´m using the profile plus module and I wan´t to hide the useless user tab of standart drupal do you have any idea how to do this? Alias I´m using 5.1.

Dirk

dldege’s picture

I've done this at the theme level in the past using this snippet.

http://drupal.org/node/68792

It works fine in 5.1.

I don't think you can do it from an admin interface or permissions thing.

dLd

designwork’s picture

Hi dldege,

I solved that problem. But I have a few others with that module.

1. If I want to search two terms like Place and Profession I got no results.

2. The hook_form_alter(). does not work with me. I can not chose any thing here? Is that an sql implode problem?

3. I have no possibility to use the function "profileplus_admin_settings" there is no menu item. I had it once but at the moment it shows nothing............

So I´m sitting here and trying to solve this Problems if you have any idea I would be gracefull. Alias I´m using the 5.1 version of Drupal.

Warm regards from Cologne

Dirk

dldege’s picture

Hi Dirk,

Unfortunately, you can only search for a single term (it treats multiple strings as one phrase). This is a limitation of the SQL query currently being used. To do multiple keywords would required a more robust query like is being done in the node search routines.

The items added in hook_form_alter are only profile fields that have a public listing page associated with them - please verify that first. That is, only fields that define pages such as

?q=profile/profile_city/Los+Angeles

Here is the query

SELECT * FROM {profile_fields} WHERE visibility = %d AND page IS NOT null AND page != "" ORDER BY category, weight
function profileplus_get_browse_fields() {
  $sql = 'SELECT * FROM {profile_fields} WHERE ';
  $filters = array();
  $filters[] = 'visibility = %d';
  $args[] = PROFILE_PUBLIC_LISTINGS;
  $filters[] = 'page IS NOT null';
  $filters[] = 'page != ""';
  $sql .= implode(' AND ', $filters);
  $sql .= ' ORDER BY category, weight';
  return db_query($sql, $args);
}

I know it works in 5.1 because I'm using it - let me know if you have a test site and I'd be happy to take a look or help you as I'm able.

dL

designwork’s picture

Hi Dldege,

i allready solved some of my problems. But I will rewrite that module.

1. I will implement a diiferent sql query. I need multiple keywords. But I don´t need user as nodes

2. I will change the admin settings, I want the admin to chose wich profile_fields will be included in the search (but this is optional)

I took over a job from a friend to develop a communityside. But normaly I´m working with Joomla or Ruby. Sunday I started with drupal and I found it quite different from the other CMS. My only problem is time, I have to present a stable version in four weeks.

And after four days allready I know that I need to review a lot of modules because there are not working, like image.module (its a side for photographers) the vcard is very bad but at least I made it run today not perfekt but a beginning. I still have just a vage idea what cck does, but i will need it etc......

But when I finish the profileplus.module i will post it back. Do you know how to do that? I think on Monday I will have a stable version of it. One more question the module is searching in the sql table profile_fields. My question is if it is not better to search in profile_value table? Because in my table profile_fields i have no categories defined. But i have in the other?

If you have a hint.....
I will post the test side on Monday, I let you know :)

Thanks for the help

Dirk

dldege’s picture

There is 2 different parts.

They keyword search is just looking in profile_values for matching text but it must consult the profile_fields table to find out which fields are public.

The second part is the drop down browse by category. That must examine the profile_fields table to find the same information and to build the form input fields. When the browse items are submitted that ends up eventuallly just redirecting to ?q=profile/FIELD_ID/VALUE which runs the actual query and builds the results page.

I don't have CVS access - the best way to submit your code would be to the profileplus project page issue tracker - http://drupal.org/project/profileplus - but I'm not sure this module is being maintained at all. Some form of this profile searching should be submitted as a core patch in my opinion.

dLd

scor’s picture

1. I will implement a diiferent sql query. I need multiple keywords. But I don´t need user as nodes

There is a patch for this problem: http://drupal.org/node/76704#comment-217321

dldege’s picture

It had a few bugs in it but I was able to manually roll it into the modified version of profileplus I posted above. It seems like it could all be done with one query if your SQL was really good but I don't see a big problem doing the queries in a for loop.

/*
 * Implementation of hook_search()
 */
function profileplus_search($op = 'search', $keys = null) {
  global $user;
  switch ($op) {
    case 'name':
      if (user_access('access user profiles')) {
        return t('Profiles');
      }
    case 'search':
      if (user_access('access user profiles')) {
      
        // Check if a browse option was submitted
        $result = profileplus_get_browse_fields();
        while ($field = db_fetch_object($result)) {
          if ($value = search_query_extract($keys, $field->name)) {
            drupal_goto('profile/'.$field->name.'/'.urldecode($value));
            exit();
          }
        }
        
        //If not browsing do a normal search
        $find = array();
        
        // Replace wildcards with MySQL/PostgreSQL wildcards.
        $keys = preg_replace('!\*+!', '%', $keys);
        $keywords = explode(' ', check_plain(strip_tags($keys)));               
        $i = count($keywords);
               
        if ($i > 0) {
          $users = array();
          $match = array();
          while ($i > 0) {
            $j = $i - 1;
            if (user_access('administer users')) {
              //administrators don't have restrictions
              $sql = "FROM {users} u INNER JOIN {profile_values} pv ON u.uid = pv.uid INNER JOIN {profile_fields} pf ON pv.fid = pf.fid WHERE pv.value LIKE '%%%s%%' OR u.name LIKE '%%%s%%'";
              $result = db_query('SELECT DISTINCT u.* ' . $sql, $keywords[$j], $keywords[$j]);
            }
            else {
              //non-administrators can only search public fields and active users
              $sql = "FROM {users} u INNER JOIN {profile_values} pv ON u.uid = pv.uid INNER JOIN {profile_fields} pf ON pv.fid = pf.fid WHERE (pv.value LIKE '%%%s%%' OR u.name LIKE '%%%s%%') AND (pf.visibility IN (%d, %d) AND u.status = 1 AND u.uid > 1)";
              $result = db_query('SELECT DISTINCT u.* ' . $sql, $keywords[$j], $keywords[$j], PROFILE_PUBLIC, PROFILE_PUBLIC_LISTINGS);
            }

            //drupal_set_message($sql);
            //drupal_set_message($keywords[$j]);
            while ($auser = db_fetch_object($result)) {
              if (in_array($auser->uid,$users) && !in_array($auser->uid,$match))
                $match[] = $auser->uid;
              else
                $users[] = $auser->uid;
            } 
            $i = $i - 1;
          }
 
          if ($match)
            $items = $match;
          else
            $items = $users;
        }
        
        $fields = array();
        $fieldsresult = db_query('SELECT name, title, type, weight, page FROM {profile_fields} WHERE visibility = %d ORDER BY weight', PROFILE_PUBLIC_LISTINGS);
        while ($record = db_fetch_object($fieldsresult)) {
          $fields[] = $record;
        }
        
        //drupal_set_message('SELECT uid FROM {users} WHERE uid IN (' . implode(', ', $items) . ')');

        if (count($items) > 0) {
          $pager = pager_query('SELECT uid FROM {users} WHERE uid IN (' . implode(', ', $items) . ')', variable_get('profileplus_results_per_page', 5));
          while ($pageditems = db_fetch_object($pager)) {
            $account = user_load(array('uid'=>$pageditems->uid));
            $profile = _profile_update_user_fields($fields, $account);
            $find[] = array('snippet' => theme('profile_listing', $account, $profile));
          }
        }
        else
          $find[] = array('snippet' => "No matches were found.");

        return $find;
      }
    }
}

dLd

sunnygambino’s picture

Dear Dldege!
I use this module. This is cool! :) I can install it, that was simply. But when I click to Search-->Profiles the Browse by Category is empty. Whats wrong?

Write back as soon as you can!
Thanks

gaijinu’s picture

Did you added the function from http://drupal.org/node/119088#comment-213380 to your profileplus.module?

Muay Thai Singapore

nishitdas’s picture

Bookmarked
Thanks dldege for the nice work

faqing’s picture

Just use the site_user_list module to search any fields of profile by option.
http://drupal.org/project/site_user_list

jayakrishnan-1’s picture

Is there anyway to disable showing the user list in the main page of site user list. I don want it to list the users by default. I just want the search results to show

Thanks
Jay

rocknet’s picture

Hello, Have you found a solution to this problem as I would also like to be able to search users by other field types, not just user name.

jayakrishnan-1’s picture

site user list. Its very easy to set up