How to search word by word using this approach (datatables)? - mysqli

Here's the code I'm using it only search (starts with first letter to last) not word by word. How is it possible to make it word by word(keyword)?
<?php
/* Database connection start */
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "sample";
$conn = mysqli_connect($servername, $username, $password, $dbname) or die("Connection failed: " . mysqli_connect_error());
mysqli_set_charset($conn,"utf8");
/* Database connection end */
// storing request (ie, get/post) global array to a variable
$requestData= $_REQUEST;
$columns = array(
// datatable column index => database column name
0=> 'app_id',
1 =>'fullname',
);
// getting total number records without any search
$sql = "SELECT app_id";
$sql.=" FROM applicants";
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.php: get employees");
$totalData = mysqli_num_rows($query);
$totalFiltered = $totalData; // when there is no search parameter then total number rows = total number filtered rows.
$sql = "SELECT app_id, fullname";
$sql.=" FROM applicants WHERE 1=1";
if( !empty($requestData['search']['value']) ) { // if there is a search parameter, $requestData['search']['value'] contains search parameter
$sql.=" AND ( app_id LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR fullname LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR contact LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR address LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR photo LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR datereg LIKE '".$requestData['search']['value']."%' )";
}
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.php: get employees");
$totalFiltered = mysqli_num_rows($query); // when there is a search parameter then we have to modify total number filtered rows as per search result.
$sql.=" ORDER BY ". $columns[$requestData['order'][0]['column']]." ".$requestData['order'][0]['dir']." LIMIT ".$requestData['start']." ,".$requestData['length']." ";
/* $requestData['order'][0]['column'] contains colmun index, $requestData['order'][0]['dir'] contains order such as asc/desc */
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.php: get employees");
$data = array();
while( $row=mysqli_fetch_array($query) ) { // preparing an array
$nestedData=array();
$nestedData[] = $row["app_id"];
$nestedData[] = $row["fullname"];
$data[] = $nestedData;
}
$json_data = array(
"draw" => intval( $requestData['draw'] ), // for every request/draw by clientside , they send a number as a parameter, when they recieve a response/data they first check the draw number, so we are sending same number in draw.
"recordsTotal" => intval( $totalData ), // total number of records
"recordsFiltered" => intval( $totalFiltered ), // total number of records after searching, if there is no searching then totalFiltered = totalData
"data" => $data // total data array
);
echo json_encode($json_data); // send data as json format
?>
The problem: it'ss start to first letter to last letter not WORD by WORD. Is it possible to make it word by word?
source

You can use REGEXP and the [[:<:]] and [[:>:]] word-boundary markers to match words only.
For example:
SELECT *
FROM table
WHERE keywords REGEXP '[[:<:]]word[[:>:]]'
Also you need to escape data with mysqli_real_escape_string().
See updated code below:
// If there is a search parameter
if( !empty($requestData['search']['value']) ) {
$search = mysqli_real_escape_string(
$conn,
// Match beginning of word boundary
"[[:<:]]".
// Replace space characters with regular expression
// to match one or more space characters in the target field
implode("[[.space.]]+",
preg_split("/\s+/",
// Quote regular expression characters
preg_quote(trim($requestData['search']['value']))
)
).
// Match end of word boundary
"[[:>:]]"
);
$sql.=" AND ( app_id REGEXP '$search' ";
$sql.=" OR fullname REGEXP '$search' ";
$sql.=" OR contact REGEXP '$search' ";
$sql.=" OR address REGEXP '$search' ";
$sql.=" OR photo REGEXP '$search' ";
$sql.=" OR datereg REGEXP '$search' )";
}
As an alternative you may look into using full-text search.

If I understand you correctly - you're referring to the fact that the search is triggered by the keyup event in the search box. This javascript will allow the user to enter a word and then hit enter to perform the search.
This need to be added to the same js file that contains the datatables initialisation code, and goes AFTER the init code:
var oTable = $('#example').dataTable({
... yourdatatable init code
// unbind the keyup event that triggers the search
$("#example_filter input").unbind();
// use fnFilter() to perform the search when the `Return` key is pressed
$("#example_filter input").keyup(function (e) {
if (e.keyCode === 13) {
oTable.fnFilter(this.value);
}
});
This assumes datatables v1.9. If you're using 1.10 there's a SO answer here which outlines the modifications
working version -> https://jsfiddle.net/markps/HEDvf/3225/

here's the solution provided by: Gyrocode.com
// If there is a search parameter
if( !empty($requestData['search']['value']) ) {
$search = mysqli_real_escape_string(
$conn,
// Match beginning of word boundary
"[[:<:]]".
// Replace space characters with regular expression
// to match one or more space characters in the target field
implode("[[.space.]]+",
preg_split("/\s+/",
// Quote regular expression characters
preg_quote(trim($requestData['search']['value']))
)
).
// Match end of word boundary
"[[:>:]]"
);
$sql.=" AND ( app_id REGEXP '$search' ";
$sql.=" OR fullname REGEXP '$search' ";
$sql.=" OR contact REGEXP '$search' ";
$sql.=" OR address REGEXP '$search' ";
$sql.=" OR photo REGEXP '$search' ";
$sql.=" OR datereg REGEXP '$search' )";
}

Related

PHP Remove All Non-alphanumeric Characters Except Apostrophes

$keywords = explode("\n",$_POST['keywords']);
//Inserting into Database
foreach($keywords as $key => $keyword){
$keyword = strtolower(trim($keyword));
$keyword = preg_replace("/[^A-Za-z0-9' ]/", "", $keyword);
$keyword = preg_replace("/\s+/", " ", $keyword);
$insertkeywords = "INSERT IGNORE INTO kwdb (keyword) VALUES ('$keyword')";
mysql_query($insertkeywords);
}
I can't for the life of me figure out why this code won't insert the keywords into the database when I have an apostrophe in the:
"/[^A-Za-z0-9' ]/"
But when I remove it to be:
"/[^A-Za-z0-9 ]/"
This script inserts records into the database.
What am I trying to do?
I have a textarea on a form. For each keyword on a new line, I explode based on the \n. I want to remove all non-letter and non-number characters from the keywords but don't want apostrophes to be removed.
I basically want all keywords to be lower-case with leading, trailing and extra white spaces - 2 or more blank spaces trimmed down to one - removed along with any non-letter and non-number characters except for apostrophes.
You need to escape your keyword: $insertkeywords = "INSERT IGNORE INTO kwdb (keyword) VALUES ('".mysql_real_escape_string($keyword)."')";
Thank you clover. Without your help, it would have taken me many hours to figure that one out! I ended up using mysqli_real_escape_string instead of mysql_real_escape_string because mysql_real_escape_string says it is deprecated as of PHP 5.5.0. As a result, I had to change it up a bit but the below code seems to work great for me so far (in case anyone else runs across this).
$con = mysqli_connect("localhost","username","password");
if (!$con)
{
die('Could not connect: ' . mysqli_error());
}
else
{
echo "Connected Successfully!";
}
//select database
mysqli_select_db($con, "test");
$keywords = explode("\n",$_POST['keywords']);
//Inserting into Database
foreach($keywords as $key => $keyword){
$keyword = preg_replace("/[^A-Za-z0-9' ]/", " ", $keyword);
$keyword = preg_replace("/\s+/", " ", $keyword);
$keyword = strtolower(trim($keyword));
//$insertkeywords = "INSERT IGNORE INTO kwdb (keyword) VALUES ('$keyword')";
$insertkeywords = "INSERT IGNORE INTO kwdb (keyword) VALUES ('".mysqli_real_escape_string($con, $keyword)."')";
mysqli_query($con, $insertkeywords);
}

Virtuemart / User Fields

I have added a field in 'Manage User Fields' & when an email is sent to the administrator notifying them of the new user registration, I want to include this new field.
I have written some code to get this new field from #__vm_user_info in /administrator/components/com_virtuemart/classes/ps_shopper.php, in the _sendMail function, as well as added the variable to $message2.
ASEND_MSG has been modified to accept the parameter, but the field is not included in the email to the admin when a user is created. When I go look in the table, the data is there. So to trouble shoot, I hard coded a user name in the select statement, added another user & the correct value was sent for the hard coded user, not the one just added. I am now thinking that it is a commit issue with MySQL, so I put a sleep(4) in the code before I attempt to get the value...no luck.
Can anyone shine some light on this for me??
LarryR....
administrator/components/com_virtuemart/classses/ps_shopper.php
Need to add with the following code in function add() before "return true" line :
/**************************** ***********************/
$pwd = $_POST['password'];
$db = JFactory::getDBO();
$query = "SELECT id, name, email, username"
. "\n FROM #__users"
. "\n ORDER by id DESC LIMIT 1"
;
$db->setQuery( $query );
$rows = $db->loadObjectList();
$namee = $rows[0]->name;
$emaill = $rows[0]->email;
$usern = $rows[0]->username;
$pwd;
$lid = $rows[0]->id;
$dbv = new ps_DB;
echo $query = "SELECT *"
. "\n FROM #__{vm}_user_info"
. "\n WHERE user_id=$lid"
;
$dbv->setQuery( $query );
$fid = $db->loadObjectList();
$field = $fid[0]->extra_field_1;
$user = clone(JFactory::getUser());
$usersConfig = &JComponentHelper::getParams( 'com_users' );
if ($usersConfig->get('allowUserRegistration') == '0') {
JError::raiseError( 403, JText::_( 'Access Forbidden' ));
return false;
}
// If user activation is turned on, we need to set the activation information
$useractivation = $usersConfig->get( 'useractivation' );
if ($useractivation == '1')
{
jimport('joomla.user.helper');
$user->set('activation', md5( JUserHelper::genRandomPassword()) );
$user->set('block', '1');
}
$component = 'com_user';
$activation_link = $mosConfig_live_site."/index.php?option=$component&task=activate&activation=".$user->get('activation');
$this->_sendMail( $namee , $emaill, $usern, $pwd, $activation_link);
/************************************************** Spinz ********************************************/
Note : Here we created the mail function for username and password to users mail.
administrator/components/com_virtuemart/classses/ps_shopper.php
Need to comment the line in function register_save() before "return true" line:
// Send the registration email
//$this->_sendMail( $name, $email, $username, $password, $activation_link );
Note: Here the mail function generated we need to comment that mail functions and create another mail function in add() function of ps_shopper.php in first point.
administrator/components/com_virtuemart/classses/ps_shopper.php
Need to get the extra added field (extra_field_1) in jos_vm_user_info table in the function _sendmail() with following code and that field sent through the mail to user.
/****************************************************************/
$db = JFactory::getDBO();
$query = "SELECT id, name, email, username"
. "\n FROM #__users"
. "\n ORDER by id DESC LIMIT 1"
;
$db->setQuery( $query );
$rows = $db->loadObjectList();
$lid = $rows[0]->id;
$dbv = new ps_DB;
$query = "SELECT *"
. "\n FROM #__{vm}_user_info"
. "\n WHERE user_id=$lid"
;
$dbv->setQuery( $query );
$fid = $db->loadObjectList();
$field = $fid[0]->extra_field_1;
$subject = sprintf ($VM_LANG->_('SEND_SUB',false), $name, $mosConfig_sitename);
$subject = vmHtmlEntityDecode($subject, ENT_QUOTES);
if ($mosConfig_useractivation=="1"){
$message = sprintf ($VM_LANG->_('USEND_MSG_ACTIVATE',false), $name, $mosConfig_sitename, $activation_link, $mosConfig_live_site, $username, $pwd, $field );
} else {
$message = sprintf ($VM_LANG->_('PHPSHOP_USER_SEND_REGISTRATION_DETAILS',false), $name, $mosConfig_sitename, $mosConfig_live_site, $username, $pwd, $field);
}
/*************************************/
Note :
Initialize the variable "$field" get the extra added field value using query. Then that the extra field value is assigned by message section of the mail.(initialize variable $field having the a value added extra fields in virtuemart).
administrator/components/com_virtuemart/languages/common/english
replace the messages for the following code:
'USEND_MSG_ACTIVATE' => 'Hello %s,
Thank you for registering at %s. Your account is created and must be activated before you can use it.
To activate the account click on the following link or copy-paste it in your browser:
%s
After activation you may login to %s using the following username and password:
Username - %s
Password - %s
Degree - %s'
2.'PHPSHOP_USER_SEND_REGISTRATION_DETAILS' => 'Hello %s,
Thank you for registering at %s. Your customer account has been created.
You may login to %s using the following username and password:
Username - %s
Password - %s
Degree - %s
'
Note:
The extra added values assigned by the string %s in language file.
The message having the string values of extra added field value in virtuemart.
The degree shows the added extra field

Postgresql lowercase to compare data

I want to get the contents from a row in the Postgresql database and compare the lowercase version of it to a lowercase version of a user input to check if it exists in the database.
i tried:
"SELECT LOWER(name) FROM user_names WHERE name LIKE '%$search%' ORDER BY name ASC"
but that make query not working at all.
EDIT
I am trying to implement an autocomplete Jquery UI like here:
http://jqueryui.com/demos/autocomplete/#remote
for search box (for names)
using javascript and php.
php code:
$search = ($_GET['term']);
if (!$con)
{ die('Could not connect: ' . pg_last_error ());}
else
{
$sql = "SELECT name FROM users_table WHERE name LIKE '%$search%' ORDER BY name ASC";
$result = pg_query($sql);
$json = '[';
$first = true;
while ($row = pg_fetch_array($result))
{
if (!$first) { $json .= ','; } else { $first = false; }
$json .= '{"value":"'.$row['name'].'"}';
}
$json .= ']';
echo $json;
exit();
}
JavaScript code:
$(document).ready(function()
{
$('#auto').autocomplete(
{
source: "./file.php",
minLength: 3
})
})
all above work great.. exactly like in Demo here: http://jqueryui.com/demos/autocomplete/#remote
my problem is that the names in database stored in Uppercase (e.g. LORI)
and of course the user prefers to insert a lowercase in search box to search for name (e.g. lori). but since it stored in uppercase, i need to convert it.
i tried as your suggestion :
$sql = "SELECT LOWER(name) FROM users_table WHERE name ILIKE '%$search%' ORDER BY name ASC";
then i got an empty drop down list!
pretty weird!
thanks in advance.
Google is your friend:
SELECT LOWER(name) FROM user_names
WHERE name ILIKE '%$search%' ORDER BY name ASC

Lucene Search doesn't find keyword indexed fields

i save my fieldes with this code:
class Places_Search_Document extends Zend_Search_Lucene_Document{
public function __construct($class, $key, $title,$contents, $summary, $createdBy, $dateCreated)
{
$this->addField(Zend_Search_Lucene_Field::Keyword('docRef', "$class:$key"));
$this->addField(Zend_Search_Lucene_Field::UnIndexed('class', $class));
$this->addField(Zend_Search_Lucene_Field::UnIndexed('key', $key));
$this->addField(Zend_Search_Lucene_Field::Keyword('title', $title ,'UTF-8'));
$this->addField(Zend_Search_Lucene_Field::unStored('contents', $contents , 'UTF-8'));
$this->addField(Zend_Search_Lucene_Field::text('summary', $summary , 'UTF-8'));
//$this->addField(Zend_Search_Lucene_Field::UnIndexed('createdBy', $createdBy));
$this->addField(Zend_Search_Lucene_Field::Keyword('dateCreated', $dateCreated));
}
}
i search the word with this code:
$index = Places_Search_Lucene::open(SearchIndexer::getIndexDirectory());
$term = new Zend_Search_Lucene_Index_Term($q);
$query = new Zend_Search_Lucene_Search_Query_Wildcard($term);
$results = $index->find($query);
now it work perfect for unsorted and text fields , but it doesn`t search for keyword !!
Are you sure you really want those fields to be keyword analyzed? The keyword analyzer puts the whole text of the field as one token, which you rarely want.

How can I get the date of an email using Perl's Mail::MboxParser::Mail?

This is a simple question. I have a little program here that reads
a list of emails in a specific inbox of a user account specified by the program.
I can access an account using its username, password and host. The only problem is I don't know how to get the date on each of these mails.
Here's some part of my code:
my $pop = new Mail::POP3Client(
USER => $user, #some user,password & host assigned
PASSWORD => $pass,
HOST => $host );
for( $i = 1; $i <= $pop->Count(); $i++ ) {
#header = $pop->Head($i);
#body = $pop->Body($i);
$mail = new Mail::MboxParser::Mail(\#header, \#body);
$user_email = $mail->from()->{email
print "Email:".$user_email; #this prints out right
foreach( $pop->Head( $i ) ) {
/^(Date):\s+/i && print $_, "\n";
$date = $_;
}
}
Now what i need is to get the only one date for each email,
but that loop gives me all.. but when remove the loop, it
returns an error. I'm using Perl.
Kindly help me? :)
According to MboxParser::Email doc, you should be able to do:
$date = $mail->header->{'date'}; #Keys are all lowercase
If you have more than one date returned, $date will be an array ref and you can access the first occurence of the Date with:
$date->[0];
So you shouldn't need to loop through the header and use a regular expression.