Page 1 of 1

[SOLVED] CG User Directory Search (for all terms)

Posted: Wed Oct 05, 2011 3:32 pm
by NikNak
Hi

I am using FrontEndUsers 1.15.4
CGUserDirectory 1.2.6
on CMSMS 1.9.4.2

Using a search form for the users works fine if only one property is entered, or if "any" is selected. However, if you enter data on more than one field and select "all", no results are returned even if you know there should be matching data.

EG
I have a user with propvals first_name = John, last_name=Doe
Setting a search with John and Doe in the correct fields of the form returns nothing. Using the debug feature from the config file, I can see that the sql that is generated is:

SELECT COUNT(U.id)
FROM
cms_module_feusers_users U
LEFT JOIN cms_module_feusers_properties P
ON U.id = P.userid
WHERE
(P.title = 'last_name' AND P.data REGEXP 'Doe')
AND
(P.title = 'first_name' AND P.data REGEXP 'John')
LIMIT 1

In phpMyAdmin this returns nothing, though if you try just for John, or for Doe, you get results for the same user.

Is there something wrong with the SQL? (not my strong point).

Has anyone else got a multi input query to work?

Many thanks

Nik




ADDENDUM -
After playing around with the sql to get the result I figure the module is trying to get, I came up with this, by adding a join for each additional search parameter. - (not that I can use this in the module! nor solve the problem). Please correct me if this is all rubbish! :-) I'm just trying to figure out what the problem is.

SELECT COUNT(U.id)
FROM
cms_module_feusers_users U

LEFT JOIN cms_module_feusers_properties P
ON U.id = P.userid

LEFT JOIN cms_module_feusers_properties P2
ON U.id = P2.userid

WHERE
(P.title = 'last_name' AND P.data REGEXP 'Doe')
AND
(P2.title = 'first_name' AND P2.data REGEXP 'John')
LIMIT 1

[SOLVED] Re: CG User Directory Search (for all terms)

Posted: Thu Oct 06, 2011 10:19 am
by NikNak
[ADDED: Calguy has now fixed this issue for the next release I believe]

If anyone is interested - I have posted a bug report to Calguy and workaround (that worked in my case) here - http://dev.cmsmadesimple.org/bug/view/6932

If there is a better solution, or if I am mistaken, please comment.

Many thanks

Nik

Re: [SOLVED] CG User Directory Search (for all terms)

Posted: Fri Jun 22, 2012 10:31 am
by jantino
Hi NikNak,

How did you manage to make the CGUserdirectory search on multiple props?

What does your search template look like? Could you share? And what does the smarty tag look like?

i've this now:
{CGUserDirectory action=search searchproperty="someprop"}
how do i add more searchable things to it?

Many thanks in front!

Re: [SOLVED] CG User Directory Search (for all terms)

Posted: Fri Jun 22, 2012 11:44 am
by NikNak
Hi Jantino

In the end I had to give up on this - there were more problems arising, and the simple solution was to avoid searching on multiple fields.

Sorry :-(

Re: [SOLVED] CG User Directory Search (for all terms)

Posted: Fri Jun 22, 2012 11:53 am
by jantino
Hi NikNak,

Thank you for your quick reply, i'll try to find a solution. When I do, i'll post it here.

Re: [SOLVED] CG User Directory Search (for all terms)

Posted: Mon Jun 25, 2012 4:45 pm
by jantino
Alright i've created an UDT. Paste the following code into an new udt and name it 'search_feu'
You can use it on a any page of your site by putting this in your content block:
{search_feu zoektermen="prop1,username,blah" sortby="price,prop3,WhateverYou'veDeclaredInTheFEUmod"}

zoektermen=comma separated properties on which the visitor may search

and sortby=comma separated properties on which the visitor may sort

Ah, don't forget to use both jQuery and jQuery forms!

Big thank you to digitaldaan for helping me with the sql queries

Code: Select all

//Load vars from smarty tag en put them in an array:
$zoektermen = $params['zoektermen']; 
$zoekterm = explode(",", $zoektermen);
$sortbyoptions = $params['sortby']; 
$sortby = explode(",", $sortbyoptions);

//If form is posted

if($_POST['sendcheck'] == "send") {

//build query
$sqlnew = "
SELECT P.userid as uid, P.title as title, P.data as data, O.title as sortingname, O.data as sortingdata 
FROM
cms_module_feusers_users U 
LEFT JOIN cms_module_feusers_properties P ON U.id = P.userid
LEFT JOIN cms_module_feusers_properties O ON U.id = O.userid 
";

//Declare array with search vars
$zoek_array = array();

//Loop trough all search vars
for($i=0; $i < count($zoekterm); $i++)
    {
       //if search option exists in posted vars
       if (array_key_exists($zoekterm[$i], $_POST)){
          //get selected items
          $term = $_POST[$zoekterm[$i]];
          if (is_array($term)){
          //loop through selected items and build query
          for($a=0; $a < count($term); $a++)
              {
                     $zoek_array[] = "(P.title = '" . $zoekterm[$i] . "' AND P.data like '%".mysql_real_escape_string($term[$a])."%')";
              }
          } else {
                 if (strlen($term) > 0){
                     $zoek_array[] = "(P.title = '" . $zoekterm[$i] . "' AND P.data like '%".mysql_real_escape_string($term)."%')";
                 }
          };
      }
    }
//if a sorting option has been clicked, use it
if (strlen($_POST['sortby']) > 0){
    $zoek_array[] .= "(O.title = '". mysql_real_escape_string($_POST['sortby']) ."')";
}

//if nothing is selected, then there should be no "where" in the sql
if (count($zoek_array) > 0) {$sqlnew .= " WHERE ";};

//get all search queries and glue them together
$zoek = implode(' AND ', $zoek_array);
$sqlnew .= $zoek;

$sqlnew .= " GROUP BY P.userid";
//again if sorting thingie has been clicked, use it
if (strlen($_POST['sortby']) > 0){
    $sqlnew .= " ORDER BY sortingdata ";
}
//asc or desc sorting switching is done by jquery by updating 2 hidden input vals.
if (strlen($_POST['ascdesc']) > 0){
    $sqlnew .= mysql_real_escape_string($_POST['ascdesc']);
}
//to check the sql query uncomment the following line
//echo "<br><br>-- " . $sqlnew . " -- <BR><BR>";


//Call cmsms smarty stuff so we can call the module cguserdirectory
$gCms = cmsms();
$smarty = &$gCms->GetSmarty();
$smarty_data = "";
 



//fetch results and loopt through them
        $result = mysql_query($sqlnew);
        while($row = mysql_fetch_assoc($result)) {
           //do something with the data, in this case, i'm feeding the user id's back to cguserdirectory with a custom detail template for every user. Be sure to create a detail template with the name "search_results"!
            $smarty_data .= "{CGUserDirectory action=\"detail\" uid=\"$row[uid]\" detailtemplate=\"search_results\"}";

           //or just uncomment following line for simple user ids.
           //echo $row[uid] . " - ";

        };

//show users through cguserdir:
$smarty->_compile_source('temporary template', $smarty_data, $_compiled );
@ob_start();
$smarty->_eval('?>' . $_compiled);
$_contents = @ob_get_contents();
@ob_end_clean();
echo $_contents;


} else {

//declare vars
$input = "";
$keuzes_array = array();
//build form using search props
$sqlkeuze = "SELECT * FROM cms_module_feusers_propdefn U 
LEFT JOIN cms_module_feusers_dropdowns P 
ON P.control_name = U.name WHERE ";
//Loop trough all search props and build query
for($i=0; $i < count($zoekterm); $i++)
    {
        $keuzes_array[] = "(name = '" . $zoekterm[$i] . "')";
    }
$keuzes = implode(' OR ', $keuzes_array);
$sqlkeuze .= $keuzes;

//echo $sqlkeuze;
        $results = mysql_query($sqlkeuze);
        while($rows = mysql_fetch_assoc($results)) {

//row type 0 stands for text
//row type 4 stands for radio
//row type 5 stands for multiple select

           if ($rows[type] == '0'){
                $input .= "<input type=\"text\" name=\"".$rows[name]."\" value=\"".$rows[prompt]."\">".$rows[prompt]."<br>";
           };
//if you want, you could build radio buttons as well, i didn't need this, but maybe someone else does.
/*
           if ($rows[type] == '4'){
                $input .= "<input type=\"radio\" name=\"".$rows[control_name]."[]\" value=\"".$rows[option_text]."\">".$rows[option_name]."<br>";
           };
*/
           if (($rows[type] == '4') || ($rows[type] == '5')){
                $input .= "<input type=\"checkbox\" name=\"".$rows[control_name]."[]\" value=\"".$rows[option_text]."\">".$rows[option_name]."<br>";
           };
        };

//display sort options and give them an onclick event for updating hidden forms and sending form
$sort = "<div id=\"sortoptions\">";
for($i=0; $i < count($sortby); $i++)
    {
       $sort .= "<div class=\"sortoption\" onclick=\"javascript: $('#sortby').val('".$sortby[$i]."'); ascdesc(); sendForm();\">" .$sortby[$i] ."</div>";
    }
$sort .= "</div>";

//below the form is put together as well as some jquery stuff to display result without reloading the page
$output = <<<endofhtml
<form id="" method="post" action="" class="cms_form" enctype="multipart/form-data">
<input type=hidden name="sendcheck" value="send">


$input
<input type=hidden id="sortby" name="sortby">
<input type=hidden id="ascdesc" name="ascdesc">

<input class="cms_submit" value="Submit" type="submit" name="Submit" />
</form>

$sort

<div id="cms_form_message"></div>
<__script__ type="text/javascript">
$(document).ready(function() {
 $(".cms_form input[type='submit']").live('click', function(event){ 
      event.preventDefault(); 
      sendForm();
 });

});
function sendForm(){
      //alert($(".cms_form").serialize());
       var cms_form_url =  $(location).attr('href').replace( $(location).attr('hash'), '') + '/?showtemplate=false';
       console.log(cms_form_url);
       //$('#cms_form_message').html("data").show(); 
       $.ajax({
              url: cms_form_url,
              type: "POST",
              data: $(".cms_form").serialize(),
              success: function(data){
                      $('#cms_form_message').html(data).show(); }
        });
};

function ascdesc(){
    if ($('#ascdesc').val() == "desc") {
       $('#ascdesc').val('asc');
    } else {
       $('#ascdesc').val('desc');
    }
};
</__script>

endofhtml;

echo $output;
};