I am working on this program. The program displays the topics under a specific subject.
My main question is, will the DataTable work in this kind of setup?
This is the code in HTML.
<div class="table-responsive" id="subject_container">
<table id="tbl_subject" class="table table-striped">
<thead>
<tr>
<th>Chapter</th>
<th>Topic</th>
<th>Content</th>
</tr>
</thead>
<tbody id="disp_topics"></tbody>
</table>
</div>
This is the code snippet in jquery:
$(function(){
//this is only for simplification. Subjectid will be coming from a select input.
let subjectid = 1;
get_topics(subjectid);
//this part right here. If this cannot work, is there a way to make it work?
$('#tbl_subject).DataTable();
});
function get_topics(subjectid){
$.ajax({
url: 'includes/subject_handler.php',
method: 'POST',
data: {
key: 'get_topics',
subjectid: subjectid
},
success: function(data){
$('#disp_topics).html(data);
}
});
This is the code of includes/subject_handler.php:
I am using keys since there are other tasks handled by this same script file. Thank you for understanding.
if($_POST['key'] == 'get_topics'){
$subjectid = $_POST['subjectid'];
$data = '';
if(!empty($subjectid)){
$sql = "SELECT topic.subjectid, chapter, topic, content FROM topic INNER JOIN subject
ON subject.subjectid=topic.subjectid WHERE topic.subjectid = ?";
$stmt=$db->prepare($sql);
$stmt->bindValue(1, $subjectid);
$stmt->execute();
if($stmt->rowCount() > 0){
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rows as $row){
$data .= '<tr>
<td>'.$row['chapter'].'</td>
<td>'.$row['topic'].'</td>
<td>'.$row['content'].'</td>
</tr>';
}
exit($data);
}
}
}
you can use ajax attribute of data table.
$('#tbl_subject').DataTable( {
processing: true,
serverSide: true,
serverMethod: 'post',
ajax: 'includes/subject_handler.php'
columns: [
{data: 'chapter', name: 'chapter'},
{data: 'topic', name: 'topic'},
{data: 'content', name: 'content'},
]
} );
And for backend if you need to access search value you can do like this,
$requestData = $_REQUEST;
$requestData['search']['value']
In your case this is how to use it in where close.
$sql .= " AND ( chapter LIKE '" . $requestData['search']['value'] . "%' ";
$sql .= " OR topic LIKE '" . $requestData['search']['value'] . "%' ";
$sql .= " OR content LIKE '" . $requestData['search']['value'] . "%' )";
And if you need to get sorting data you can get like this,
$requestData['order'][0]['column'] // column name which user sorts
$requestData['order'][0]['dir'] // derection (ASC/DESC)
In your case it will be like this and remember to use $requestData['start'] and $requestData['length'] for pagination to work.
$sql .= " ORDER BY " . $columns[$requestData['order'][0]['column']] . " " . $requestData['order'][0]['dir'] . " LIMIT " . $requestData['start'] . " ," . $requestData['length'] . " ";
You can include this search value and order values inside your sql query inside backend.
And finally you need format the data before send to front end.
$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);
This is much simpler than looks. Need to get total records count from query, and total filtered record count from another query and dataset in json.
I have added previous sql example only to explain. For preventing SQL injection you have to use Prepared Statements.
$sql .= " AND ( chapter LIKE ? OR topic LIKE ? OR content LIKE ?";
$params = array($requestData['search']['value'] . "%", $requestData['search']['value'] . "%", $requestData['search']['value'] . "%");
$stmt = $handle->prepare($sql);
$stmt->execute($params);
And you need to do the same for ORDER BY and LIMIT part of the query.
and inside this tutorial there is a nice example how it works on backend.
You can send data to back end also like this.
ajax: {
url: "Your url",
data: function (d) {
d.var1= 'var 1';
d.var2= 'var 2';
}
},
And access the data in back end like this.
$var1 = $_REQUEST['var1'];
$var2 = $_REQUEST['var2'];
And be careful not to use start and end (E.g.:- d.start= 'var 1';) to pass data to back end since they are used for pagination. This link has a nice example on this.
Related
I am using a class to generate a string name profile to slug and next use an SQL command to tell me whats the unique value to use in insert command, the problem is the command isn't working properly, sometimes it is possible to return a value which already exist...
Thats the class I am using to generate the slug: (composer require channaveer/slug)
And this the example code:
use Channaveer\Slug\Slug;
$string = "john doe";
$slug = Slug::create($string);
$profile_count_stmt = $pdo->prepare("
SELECT
COUNT(`id`) slug_count
FROM
`advogados_e_escritorios`
WHERE
`slug_perfil` LIKE :slug
");
$profile_count_stmt->execute([
":slug" => "%".$slug."%"
]);
$profile_count = $profile_count_stmt->fetchObject();
if ($profile_count && $profile_count->slug_count > 0) {
$profile_increment = $profile_count->slug_count + 1;
$slug = $slug . '-' . $profile_increment;
}
echo 'Your unique slug: '. $slug;
// Your unique slug: john-doe-5
This is the content of the table when the script run:
Do you know how can I improve the select command to prevent it to return existing slugs from DB?
Ok finally found a solution... Heres the code for who wants to generate unique profile slugs using PHP - PDO and MySQL
$string = "John Doe";
$string = mb_strtolower(preg_replace('/\s+/', '-', $string));
$slug = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
$pdo = Conectar();
$sql = "
SELECT slug_perfil
FROM advogados_e_escritorios
WHERE slug_perfil
LIKE '$slug%'
";
$statement = $pdo->prepare($sql);
if($statement->execute())
{
$total_row = $statement->rowCount();
if($total_row > 0)
{
$result = $statement->fetchAll();
foreach($result as $row)
{
$data[] = $row['slug_perfil'];
}
if(in_array($slug, $data))
{
$count = 0;
while( in_array( ($slug . '-' . ++$count ), $data) );
$slug = $slug . '-' . $count;
}
}
}
echo $slug;
//john-doe-1
You should check if the slug exists or not from your database. If it already exists then you can append some random string like the following
$slug = Slug::create($string);
$slugExists = "DB query to check if the slug exists in your database then you may return the count of rows";
//If the count of rows is more than 0, then add some random string
if($slugExists) {
/** NOTE: you can use primary key - id to append after the slug, but that has to be done after you create the user record. This will help you to achieve the concurrency problem as #YourCommenSense was stating. */
$slug = $slug.time(); //time() function will return time in number of seconds
}
//DB query to insert into database
I have followed the same for my blog articles (StackCoder) too. Even LinkedIn follows the same fashion.
Following is screenshot from LinkedIn URL
CakePHP Version 3.5.5
What I've got:
I've got search functionality on my index pages which allows a user to search by column and value. The user selects the column from a select list and adds text into an input. I pick up this data with the following which works:
$query = $Users->find()
->where(function ($exp, $q) {
return $exp->like($this->request->getData('column'), $this->request->getData('input') . '%');
})
->andWhere([
'status' => $filter,
'cid_1' => $c1
]);
When using the debugKit it reveals the sql as: (Extract only to help explain)
FROM users Users WHERE (role LIKE :c0 AND status = :c1 AND cid_1 = :c2)',
What I'm trying to do is the following:
$testColumn = $this->request->getData('column');
$testInput = $this->request->getData('input');
$query = $Users->find()
->where(function ($exp, $q) {
return $exp->like($testColumn, $testInput . '%');
})
->andWhere([
'status' => $filter,
'cid_1' => $c1
]);
The $testColumn variable is undefined.
Whe using the debugKit it reveals the sql as: (Extract only to help explain)
FROM users Users WHERE ( LIKE :c0 AND status = :c1 AND cid_1 = :c2)',
IE: The role is not being declared before the LIKE.
What I've tried:
1. return $exp->like("$testColumn", "$testInput" . '%');
Result: Exactly the same - Variable is still undefined.
DebugKit: FROM users Users WHERE ( LIKE :c0 AND status = :c1 AND cid_1 = :c2)',
2. return $exp->like("'$testColumn'", "'$testInput'" . '%');
Result: It added '' before LIKE as can be seen below but I still can't get that variable defined.
DebugKit: FROM users Users WHERE ('' LIKE :c0 AND status = :c1 AND cid_1 = :c2)',
My Question:
Is there a way to use a dynamic value to select the search data.
Update:
Is it that I can't assign getData to a variable in this context.
You can't do this:
$testColumn = $this->request->getData('column');
return $exp->like($testColumn, $testInput . '%');
But you can do this:
$testColumn = $this->request->getData('column');
echo 'testColumn is ' . $testColumn . '<br />';
if ($testColumn === 'role') {
echo 'in column passed ' . '<br />';
}
else {
echo 'in column failed ' . '<br />';
}
Thanks. Z.
////////////////////////////////////////////////////////////////////////////////
Alimon Karim as requested.
I'm using post and my url is: https://localhost/app/users/search
Thanks Alimon, it works.
Replace
->where(function ($exp, $q) {
with
->where(function ($exp, $q) use ($testColumn,$testInput) {
I would like to filter results with several parameters: a boolean status, a category, and a keyword that would be search either on the title or the description (localized fields).
I am a newbie for this. I succeeded to make the query work when I ommit the description keyword criteria :
$advertList = new Object\Advert\Listing();
$advertList->setOrderKey("date");
$advertList->setOrder("DESC");
$conditions = [];
if ($this->getParam("keyword"))
{
$conditions[] = " title LIKE " . $advertList->quote("%" . $this->getParam("keyword") . "%");
}
if ($this->getParam("reqoffer")) {
$conditions[] = "reqoffer LIKE " . $advertList->quote("%" . $this->getParam("reqoffer") . "%");
}
if($this->getParam("category")) {
$conditions[] = "category__id = " . $this->getParam("category");
}
$advertList->setCondition(implode(" AND ", $conditions));
But when I want to add my "or condtion" :
$conditions[] = "( title LIKE " . $advertList->quote("%" . $this->getParam("keyword") . "%") .
// " OR shorttext LIKE " . $advertList->quote("%" . $this->getParam("keyword") . "% )");
I can't succeed to make my firt query on the keyword in parenthesis for the "OR" : I mean at the end, I get results even if category or reqoffer is wrong as long as title is ok...
I have been looking for many hours and tried many things. I could not find the same issue. I am sure this is obvious for some of you. Please help if you can.
Thanks in advance.
If you want to build conditions like WHERE (a AND b) OR c you need to do something like this (pseudo-code):
$or_conditions = [];
$and_conditions = [];
if (needA)
$and_conditions[] = "a";
if (needB)
$and_conditions[] = "b";
$or_conditions[] = "(" . implode(" AND ", $and_conditions) . ")";
$advertList->setCondition(implode(" OR ", $or_conditions));
theoretically I'll show you the code that works, I mean, it makes sense but I can not get no change in the table! : \
so, here is the code:
else if ($mode == 'password') {
$generated_password = substr(md5(rand(999,999999)), 0, 8);
change_password($user_data['user_id'],$generated_password);
update_user($user_data['user_id'], array('password_recover' => '1'));
email($email, 'Your new password', "Hi," . $user_data['nome'] . " \n\nYour new password is: " . $generated_password . "");
}
Functions:
function update_user($user_id,$update_data){
$update = array();
array_walk($update_data, 'array_sanitize');
foreach($update_data as $field => $data) {
$update[]='`' .$field. '`=\'' .$data . '\'';
}
mysql_query("UPDATE users SET " . implode(', ',$update) . "WHERE user_id = '$user_id'");
}
function change_password($user_id,$password) {
$user_id = (int) $user_id;
$password = md5($password);
mysql_query("UPDATE users SET password = '$password' WHERE user_id = $user_id");
}
I have not even written the email function because that works. Thanks in advance! :)
You should add some kind of error handling to your code. At least add or die('Error: '.mysql_error()) after each mysql_query() to at least get some idea of what went wrong when the queries are executed.
And if you just take code from somewhere and don't really understand what it does, don't be surprised, if it doesn't do what you want it to do.
I've a MySql table where I put some value: id, name of opportunity, category of opportunity, commission etc etc. Now I need to create (automatically) a shortcode that call these value win an array, so for example if i write [opportunity id="1"] wordpress display banner of the opportunity in the database that have id=1.
This is my code
function opportunity_banner_shortcode($atts) {
extract(shortcode_atts(array("id" => ''), $atts));
global $table_prefix, $wpdb, $user_level;
$table_name = $table_prefix . "opportunities";
$finds = $wpdb->get_results("SELECT * FROM {$table_name}", ARRAY_A);
if(sizeof($finds)){
foreach($finds as $find)
return "<a href='" . $find["opp_link"].
"'><img src='" . $find["opp_banner_preview"]."'></a> ";
}
}
add_shortcode('opportunity', 'opportunity_banner_shortcode');
Thanks to all
Maybe the query should be
$finds = $wpdb->get_results("SELECT * FROM {$table_name} WHERE id={$id}",
ARRAY_A);