Run MySQL query in DataTables server-side processing script - php

I am using DataTables server-side processing to pull data into a DataTables table from a MySQL table.
This is the working MySQL query I would like to run and display in my DataTables table:
$sql = "SELECT Client,EstimateNumber,Status,TotalEstimatedTime,CostToDateRoleTotal,ROUND((CostToDateRoleTotal/TotalEstimatedTime)*100) as PercentComplete FROM Estimates WHERE " . ($studioName != null ? "Studio = '" . $studioName. "' AND" : '') . " Status != 'Invoiced' AND Status != 'Cancelled' AND TotalEstimatedTime > 0 AND CostToDateRoleTotal > 0 ORDER BY PercentComplete DESC";
I have adjusted the DataTables server-side processing script to be:
<?php
// connection configuration
require_once 'config.php';
// db table to use
$table = 'Estimates';
// table's primary key
$primaryKey = 'EstimateNumber';
$percent_complete = "('CostToDateRoleTotal'/'TotalEstimatedTime')*100";
// array of database columns which should be read and sent back to DataTables.
// the 'db' parameter represents the column name in the database, while the 'dt'
// parameter represents the DataTables column identifier.
$columns = array(
array('db' => 'Client', 'dt' => 0),
array('db' => 'EstimateNumber', 'dt' => 1),
array('db' => 'Status', 'dt' => 2),
array('db' => 'TotalEstimatedTime', 'dt' => 3),
array('db' => 'CostToDateRoleTotal', 'dt' => 4),
array('db' => $percent_complete, 'dt' => 4),
); // end columns array
// sql server connection information
$sql_details = array(
'user' => $currentConfig['user'],
'pass' => $currentConfig['pass'],
'db' => $currentConfig['name'],
'host' => $currentConfig['host'],
);
// DataTables helper class
require 'ssp.class.php';
function utf8ize($d) {
if (is_array($d)) {
foreach ($d as $k => $v) {
$d[$k] = utf8ize($v);
}
} else if (is_string ($d)) {
return utf8_encode($d);
}
return $d;
}
$data = SSP::complex($_GET, $sql_details, $table, $primaryKey, $columns, null, "Status != 'Invoiced' AND Status != 'Cancelled' AND TotalEstimatedTime > 0 AND CostToDateRoleTotal > 0");
echo json_encode(utf8ize($data));
This line is throwing an error:
$percent_complete = "('CostToDateRoleTotal'/'TotalEstimatedTime')*100";
The error is: {"error":"An SQL error occurred: SQLSTATE[42S22]: Column not found: 1054 Unknown column '('CostToDateRoleTotal'/'TotalEstimatedTime')*100' in 'field list'"}
In my original $sql query above, I ran this calculation and displayed the outcome as a new column, $percent_complete. I am trying to display those same results in my DataTables table. How can I alter my server-side processing script to perform this calculation and display it in a new column?

CAUSE
Class SSP defined in ssp.class.php cannot handle column aliases, expressions or JOINs.
SOLUTION
You need to alter ssp.class.php and remove all ` (backtick) characters that escape column and table names. You would be responsible for escaping column/table names yourself if the name is a reserved word.
Then replace
array('db' => $percent_complete, 'dt' => 4)
with
array('db' => 'ROUND((CostToDateRoleTotal/TotalEstimatedTime)*100)', 'dt' => 4)

I don't know how the SSP class formats the query but you might want to try to add "AS percent_complete".
$percent_complete = "(CostToDateRoleTotal/TotalEstimatedTime)*100 AS percent_complete";
When you SELECT a column it needs a name.

Related

Convert Datatables array value from Integer to String

My database has a column called status which store only integer 0,1,2... Currently im listing all my database data to a datatable but how can i display my status column as string instead of the integer 0,1,2 ? I'm displaying the int value straight from database to table (which are 0,1,2), but i want to process the (0,1,2) and display (0 =Pending, 1 = Running , 2 = Completed.)
My database column :
Column Status
Image: Datatable
Expected result : Expected
PHP:
// DB table to use
$table = 'projects';
// Table's primary key
$primaryKey = 'projectID';
// Array of database columns which should be read and sent back to DataTables.
// The `db` parameter represents the column name in the database.
// The `dt` parameter represents the DataTables column identifier.
$columns = array(
array('db' => 'projectName', 'dt' => 0),
array('db' => 'projectDescription', 'dt' => 1),
array('db' => 'destinationName', 'dt' => 2),
array('db' => 'projectStatus', 'dt' => 3), //Here is the status column
array('db' => 'startDate', 'dt' => 4),
array('db' => 'endDate', 'dt' => 5)
);
// Include SQL query processing class
require 'ssp.class.php';
// Output data as json format
echo json_encode(
SSP::simple($_GET, $dbDetails, $table, $primaryKey, $columns)
);
My logic:
If (data) of projectStatus == 0 then display "Pending";
If (data) of projectStatus == 1 then display "Running";
If (data) of projectStatus == 2 then display "Completed";

Checking if selected rows are favourite by user in cakephp

I have a Venue table with 20+ columns.
I also have a favorite_venues table with columns
id | userId | venueId
Here is my code to get venues
$this->Venue->virtualFields = array(
'bookedCount' => "SELECT count(*) FROM bookings WHERE venueId = Venue.id"
);
$result = $this->Venue->find('all', array('conditions'=>$conditions,
'order' => array('Venue.bookedCount DESC'),
'limit' => 20,
'offset' => $offset * 20
));
i want to add a condition if i send userId, it should check every venue if its added to favourite list or not and set
$venue['isFavorite'] = yes/no
I dont want a for loop and check every venue i get. is there any way i can incorporate in same Mysql query in cakephp. I am not sure how to put yes/no as virtual field
You can LEFT join in your favorite_venues table, and then for example use a CASE statement in a virtual field that checks whether there is a linked row.
Here's an untested example to illustrate what I mean. I don't know how the user ID is involved, so you got to figure that on your own.
$this->Venue->virtualFields = array(
'bookedCount' => "SELECT count(*) FROM bookings WHERE venueId = Venue.id",
'isFavorite' => 'CASE WHEN FavoriteVenues.id IS NOT NULL THEN "yes" ELSE "no" END'
);
$result = $this->Venue->find('all', array(
'conditions' => $conditions,
'order' => array('Venue.bookedCount DESC'),
'limit' => 20,
'offset' => $offset * 20,
'joins' => array(
array(
'table' => 'favorite_venues',
'alias' => 'FavoriteVenues',
'type' => 'LEFT',
'conditions' => array(
'FavoriteVenues.venueId = Venue.id',
)
)
),
// don't forget to group to prevent duplicate results
'group' => 'Venue.id'
));
See also
Cookbook > Models > Virtual Fields > Virtual fields set in controller with JOINS
Cookbook > Models > Associations: Linking Models Together > Joining Tables
MySQL 5.7 Reference Manual / SQL Statement Syntax / ... / CASE Syntax

Drupal 7 Select query with If condition mysql database

function tablesort_example_page() {
//$date2=date('m-d-Y', strtotime('t.added_date'));
// if('t.status'==1){
// $status='Active';
// }else{
// $status='Inactive';
// }
// We are going to output the results in a table with a nice header.
$header = array(
// The header gives the table the information it needs in order to make
// the query calls for ordering. TableSort uses the field information
// to know what database column to sort by.
array('data' => t('S No'), 'field' => 't.id'),
array('data' => t('Country Name'), 'field' => 't.country_name'),
array('data' => t('Status'), 'field' => 't.status'),
array('data' => t('Added Date'), 'field' => 't.added_date'),
array('data' => t('Action'), 'field' => 't.id',),
array('data' => t('Action'), '',),
);
// Using the TableSort Extender is what tells the the query object that we
// are sorting.
$limit = 10;
$query = db_select('countries', 't')->extend('TableSort')->extend('PagerDefault')->limit($limit)->orderby('id', ASC);
$query->fields('t');
// Don't forget to tell the query object how to find the header information.
$result = $query
->orderByHeader($header)
->execute();
if('$row->status'==0){
$status='Active';
} else {
$status='Inactive';
}
$rows = array();
$i=1;
foreach ($result as $row) {
//print_r($row);
// Normally we would add some nice formatting to our rows
// but for our purpose we are simply going to add our row
// to the array.
$rows[] = array(
$row->id,
$row->country_name,
$status, ----> **
here i need to execute the If condition for $status
//$row->added_date,
date('d-m-Y H:i:s', strtotime($row->added_date)),
l('edit', 'mypages/countries/'. $row->id),
l('delete', 'mypages/delete/'. $row->country_name)
);
$i++;
}
As per my database table the below are my table fields.
(id, country_name, status, added_date)
In Status there will be 0 or 1
now my Question is i need to display status
if 0 - Inactive
1 - Active
I'd suggest using a PHP ternary operator to test the value in the status field and output a string description based on that value.
$rows[] = array(
$row->id,
$row->country_name,
($row->status == 0) ? 'Inactive' : 'Active',
date('d-m-Y H:i:s', strtotime($row->added_date)),
l('edit', 'mypages/countries/'. $row->id),
l('delete', 'mypages/delete/'. $row->country_name)
);

DataTables | How to do your own select?

Hello i use the tablesorter-plugin DataTables.
I use it with serverside processing and ajax pipelining.
Here is my actual serverside script:
<?php
// Datenbank-Tabelle, die verwendet wird
$table = 'loginlogs';
// Der Primary key, der Tabelle
$primaryKey = 'id';
// Das "datetime"-Format aus der Datenbank extrahieren, nur das Datum (in das Deutsche-Format)
function getonlydate($datetime){
$exploded = explode("-", $datetime);
$explodemeagain = explode(" ", $exploded[2]);
$mergeme = $explodemeagain[0].".".$exploded[1].".".$exploded[0];
return $mergeme;
}
// Das "datetime"-Format aus der Datenbank extrahieren, nur die Uhrzeit
function getonlytime($datetime){
$exploded = explode("-", $datetime);
$explodemeagain = explode(" ", $exploded[2]);
$mergeme = $explodemeagain[1];
return $mergeme;
}
// Array of database columns which should be read and sent back to DataTables.
// The `db` parameter represents the column name in the database, while the `dt`
// parameter represents the DataTables column identifier. In this case simple indexes.
$columns = array(
array( 'db' => 'ip', 'dt' => 0 ),
array(
'db' => 'status',
'dt' => 1,
'formatter' => function( $d, $row ) {
if($d == 1){
return "Erfolgreich";
}else{
return "Fehlgeschlagen";
}
}
),
array(
'db' => 'stayloggedin',
'dt' => 2,
'formatter' => function( $d, $row ) {
if($d == 1){
return "Ja";
}else{
return "Nein";
}
}
),
array(
'db' => 'date',
'dt' => 3,
'formatter' => function( $d, $row ) {
return getonlydate($d);
}
),
array(
'db' => 'date',
'dt' => 4,
'formatter' => function( $d, $row ) {
return getonlytime($d);
}
)
);
// SQL server connection information
require('../../phpfuncs/connection.php');
$sql_details = array(
'user' => $user,
'pass' => $pw,
'db' => $db,
'host' => $host
);
require('ssp.class.php');
echo json_encode(
SSP::simple( $_GET, $sql_details, $table, $primaryKey, $columns )
);
?>
Now my question is how can i do specific selects?
A specific select like:
"SELECT * FROM ".$table." WHERE userid=16"
I already searched on their website for some documentations but i can only find docs about filtering, and so on. Clientside stuff, but nothing about specific serverside possibilities.
Maybe somebody also use datatables and tablesorter and can help me out with an example?
You can use another method SSP::complex. From the comments in the code:
The difference between this method and the simple one, is that you
can apply additional where conditions to the SQL queries. These can
be in one of two forms:
'Result condition' ($whereResult) - This is applied to the result set, but not the
overall paging information query - i.e. it will not effect the number
of records that a user sees they can have access to. This should be
used when you want apply a filtering condition that the user has sent.
'All condition' ($whereAll) - This is applied to all queries that are made and
reduces the number of records that the user can access. This should be
used in conditions where you don't want the user to ever have access
to particular records (for example, restricting by a login id).
Function accepts the following arguments:
SSP::complex ($request, $conn, $table, $primaryKey, $columns, $whereResult=null, $whereAll=null)
So in order to apply the SQL query with WHERE condition, you need to change your code as follows:
echo json_encode(
SSP::complex( $_GET, $sql_details, $table, $primaryKey, $columns, null, "userid=16" )
);

CakePHP: How to retrieve data by multiple condition

Please help me to retrieve data from a table by multiple condition in Cakephp
I have one table name: article; I have tried to retrieve data with the code below
I want to get specific id as given in the parameter; article_price > 0 and article_status > 1
public function getArticle($artID = ''){
return $this->find('all', array(
'condition' => array(
'article_id =' => $artID,
'article_price' => '> 0',
'article_status = ' => '1'),
'order' => 'article_id DESC'
));
}
// the out put was selected all data without condition that I want.
What was the problem with my code?
What I found out is I print: echo $this->element ('sql_dump'); and I got the following sql statement:
SELECT `article`.`article_id`, `article`.`name`, `article`.`article_price`, `article`.`article_status` FROM `db_1stcakephp`.`article` AS `article` WHERE 1 = 1 ORDER BY `article_id` DESC
Please help me.
Thank!
If your model name is Article:
public function getArticle($art_id) {
return $this->find('first', array(
'conditions' => array(
'Article.article_id' => $art_id,
'Article.article_price >' => 0,
'Article.article_status >' => 1,
),
));
}
Using 'Model.field' syntax is optional, until your models have relationship and have the same names - for example Article.status and Author.status.
Moving comparison sign into array's key part allows you to do:
'Article.price >' => $minPrice,
'Article.price <=' => $maxPrice,
And I didn't really notice typo in 'conditions'.

Categories