Datatables not sorting date correctly Serverside - mysql

I am using server side processing, so as I understand, all sorting/ordering is done server side. However, when I click on the column header, it should send the server a post variable to apply the ASC or DESC sort order. This is not working and I'm trying to figure out where my problem lies.
I am using the default script that comes with datatables.
My dates in the database is stored as timestamp values such as 15-10-2015 10:20:30.
Now, the table displays fine, however the dates are not sorted correctly. Even if I output just the year values e.g. 2014 , it does not sort them ASC and DESC.
Instead, I get results like:
2014
2014
2015
2015
2014
2014
2015
:(
I declare the table as follows :
DemoTable = $('#table_demo').DataTable(
{
"order": [],
"aaSorting" : [],
"deferRender": true,
"bJQueryUI": true,
"bPaginate": true,
"bStateSave": true,
"processing": true,
"serverSide": true,
"sPaginationType": "full_numbers",
"ajax":
{
"url": "view_demo_remote.php",
"data":
{
"role": $_SESSION['role'],
"email": $_SESSION['email'],
"practiseid": $_SESSION['practiceid']
}
},
"columns":[
{ "data": "first_number" , "bSortable": true },
{ "data": "datecreated", "bSortable": true },
{ "data": "submitted_by"},
{ "data": "second_number"},
{ "data": "picture","bSortable": false },
{ "data": "options","bSortable": false }
],
});
On the server, I have the following section for the columns:
$columns = array(
array(
'db' => 'id',
'dt' => 'DT_RowId',
'formatter' => function( $d, $row )
{
// Technically a DOM id cannot start with an integer, so we prefix
// a string. This can also be useful if you have multiple tables
// to ensure that the id is unique with a different prefix
return $d;
}
),
array(
'db' => 'firstnumber',
'dt' => 'first_number',
'formatter' => function($d, $row)
{
$number = $d;
return substr($number, 0, 10);
}),
array(
'db' => 'datecreated',
'dt' => 'datecreated',
'formatter' => function($d, $row)
{
// DD/MM/YYYY HH:MM:SS
$date = date_create_from_format('d-m-Y H:i:s', $d);
return date_format($date, 'Y');
}),
array( 'db' => 'username', 'dt' => 'submitted_by' ),
array( 'db' => 'secondnumber', 'dt' => 'second_number' ),
array(
'db' => 'picture',
'dt' => 'picture',
'formatter' => function($d, $row)
{
return "<p style=\"padding:5px;\"><img src=\"".$d."\" alt=\"Picture\" style=\"width:auto;max-height:70px;border:1px solid #2d2d2d;-webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px; \"></img></p>";
}),
array( 'db' => 'id', 'dt' => 'options');
);
and then I have this part after the columns section:
// SQL server connection information
$sql_details = array(
'user' => DBUSER,
'pass' => DBUSERPASS,
'db' => DBNAME,
'host' => DBHOST
);
require( 'libraries/DataTables-1.10.7/examples/server_side/scripts/ssp.class.php' );
$whereAll = " firstnumber <>''";
echo json_encode(SSP::complex( $_GET, $sql_details, $table, $primaryKey, $columns, "",$whereAll));
So the table displays fine, all column headers for the sortable columns can be clicked on and it sorts ASC or DESC perfectly. However, the date does not sort perfectly. If I turn off sorting off on the table and I manually add "ORDER BY datecreated ASC" to the where clause, it works perfectly, which tells me that there is nothing wrong with my date format, however, I want sorting ON.
Please help
I have also asked a question on the datatables forums https://www.datatables.net/forums/discussion/31216/datatables-not-ordering-date-correctly

Thanks all for contributing.
At the end of the day, the problem was actually caused by a field in the database that was in the wrong format. The datecreated field was saved as a Varchar and it had to be DATETIME.
Once I fixed this in the database, everything sorted perfectly.
thanks for everyone who helped. But yes, I want to stress the fact that when server side processing is being done, all sorting / ordering is done server side. You can manipulate the format and display on the client side, but NOT the actual order, when server side is being used.

Related

ZF2 - inputFilter -> set value to null

In my ZF2 app I've got a form with several optional fields. If user decide to leave that field blank then it should set it as NULL in db, however - it doesn't work.
Example field:
$this->add(array(
'name' => 'productId',
'type' => 'select',
'options' => array(
'value_options' => array(
'global' => 'Global option', // this should be null
'mobile' => 'Another option'
)
),
));
And filter:
$inputFilter->add(array(
'name' => 'productId',
'validators' => array(
array(
'name' => 'Callback',
'options' => array(
// 'messages' => array(
// \Zend\Validator\Callback::INVALID_VALUE => $value,
// ),
'callback' => function ($value) {
if($value === 'global')
{
$value = null;
//return true;
// echo '<pre>' . var_export($value, true) . '</pre>';
// die();
}
}
),
),
),
));
This piece of code works when "mobile" option is selected. However, with 'global' option it doesn't work.
As you can see, I've done some basic debugging to make sure that value is overrided on callback and it indeed returns NULL. Regardless of that validator says:
array (
'productId' =>
array (
'callbackValue' => 'The input is not valid',
),
)
So I tried to return true on callback which resulted in below error:
Statement could not be executed (23000 - 1452 - Cannot add or update a child row: a foreign key constraint fails (app.codes, CONSTRAINT fk_products_id FOREIGN KEY (productId) REFERENCES products (id)))
How am I supposed to pass null param to my db? If I cut this field completly from form then it is ignored and everything works.
Found solution, it's pretty simple actually.
I can set desired select options to some specific value and then use ToNull filter to convert it into null -
https://framework.zend.com/manual/2.4/en/modules/zend.filter.null.html
Code for $inputFilter:
$inputFilter->add(array(
'name' => 'productId',
'required' => false,
'filters' => array(
array('name' => 'ToNull', 'options' => array('type' => \Zend\Filter\ToNull::TYPE_STRING)),
),
));

Yii2 update with multiple conditions

$this->localdb->createCommand()
->update(
$this->MYTable,
[
'name' => $el['new'],
'data' => $el['data'],
],
[
'userId', $this->user,
'product_id', $this->productId,
'name', $el['old'],
'created', $el['date'],
'category', $el['cat'],
]
);
I tried to use the following command to update a row using multiple where conditions, but it doesn't work for some reason. The documentation doesn't seem to cover this case and doesn't seem to be updated, because the update() method seems to match the updateAll method instead of the update method for some reason (maybe it was updated?). So I was wondering what was the correct way to do this.
You have a syntax error. Try following:
$this->localdb->createCommand()
->update(
$this->MYTable,
[
'name' => $el['new'],
'data' => $el['data'],
],
[
'userId' => $this->user,
'product_id' => $this->productId,
'name' => $el['old'],
'created' => $el['date'],
'category' => $el['cat'],
]
);
Try This updateAll query :
MYTable::updateAll([ // field to be updated in first array
'name' => $el['new'],
'data' => $el['data']
],
[ // conditions in second array
'userId' => $this->user,
'product_id' => $this->productId,
'name' => $el['old'],
'created' => $el['date'],
'category' => $el['cat']
]);

AutoIncrement PK incrementing irregularry

I recently release an app: https://my.kendozone.com in Laravel 5.3 / MySQL
I'm getting users, but one weird thing is that my user's id are not incrementing by one.
HERE last 10 rows id :
5401
5402
5403
5404
5405
5406
5407
5408
8359
9799
The 2 ways I save my users are :
$user = User::create([
'provider' => $provider,
'provider_id' => $userData->id,
'name' => $userData->name,
'firstname' => $userData->name,
'slug' => str_slug($userData->name),
'email' => $userData->email,
'avatar' => $avatar,
'role_id' => config('constants.ROLE_USER'),
'verified' => 1,
]);
or
$user = User::create(['name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'role_id' => config('constants.ROLE_USER'),
'verified' => 1,
]);
How should understand this??? Is it normal???
Does anybody have an explanation???
My id are weird because of my Functional tests.
when running, they use :
use DatabaseTransactions
that mean that all queries runs into a Transaction, but I guess it uses ids range.

Why memcache Yii2 not set value with duration parameter

I using Memcache to cache data in project yii2.
with config:
'cache' => [
'class' => 'yii\caching\MemCache',
'servers' => [
[
'host' => 'localhost',
'port' => 11211,
],
],
],
With code: return false
\Yii::$app->cache->set('abc', 'value of abc', 20); // 20 seconds
$data = \Yii::$app->cache->get('abc'); var_dump($data); // return false
But if i set:
\Yii::$app->cache->set('abc', 'value of abc', -20); // -20 seconds $data = \Yii::$app->cache->get('abc'); var_dump($data); // return "value of abc"
So why this? Thanks.
Can you increment the seconds?
Pls try this and let me know the results:
\Yii::$app->cache->set('abc', 'value of abc', 10000);
$data = \Yii::$app->cache->get('abc'); var_dump($data);
A bit late, but in case someone else have same problem, here are my thoughts...
It might depend on whether MemCached or MemCache is installed. If config uses MemCache (like in the question) but MemCached is installed, it will work using get() but set() is different after the two first parameters, ie duration.

Datatables : Make a parallel request in another table using ServerSide

EDIT : I found the solution by replacing the SSP class by a customized SSP class I've found here : https://github.com/emran/ssp
I don't know if it's an understandable title, but here is my problem :
I have a DB-table (called projects) that needs to be inserted in a datatable. I've no problem to make a call using ServerSide and get results in the datatable.
But, for each project (each row), there is a project creator (column creator_id in the projects DB-table). What I need to do is to make a request to the creators DB-table in order to get the firstname/lastname of the creator, each time I get a row from the projects DB-table. Is that make sense?
Here is the code I use :
$table = 'projects';
$primaryKey = 'project_id';
$columns = array(
array(
'db' => 'project_id',
'dt' => 'DT_RowId',
'formatter' => function( $d, $row ) {
return $d;
}
),
array( 'db' => 'creator_id',
'dt' => 'creator',
'formatter' => function( $d, $row ) {
// Here I need to make a call to the creators DB-table and return the $creator_name value
return $creator_name;
}
)
);
// SQL server connection information
$sql_details = array(
'user' => '',
'pass' => '',
'db' => '',
'host' => ''
);
require(BASE_DIR.'/lib/dataTables/ssp.class.php');
$result = SSP::simple($_GET, $sql_details, $table, $primaryKey, $columns);
You can use formatter property to make a separate SQL query but it will affect performance greatly by increasing script response time.
Instead you can use the following trick when using ssp.class.php with sub-queries instead of table name to use GROUP BY, JOIN, etc.
<?php
$table = <<<EOT
(
SELECT projects.project_id, creators.creator_id, creators.creator_name
FROM projects
LEFT JOIN creators ON projects.creator_id=creators.creator_id
) t
EOT;
$primaryKey = 'project_id';
$columns = array(
array(
'db' => 'project_id',
'dt' => 'DT_RowId'
),
array(
'db' => 'creator_id',
'dt' => 'creator'
),
array(
'db' => 'creator_name',
'dt' => 'creator_name'
)
);
// SQL server connection information
$sql_details = array(
'user' => '',
'pass' => '',
'db' => '',
'host' => ''
);
require(BASE_DIR.'/lib/dataTables/ssp.class.php');
$result = SSP::simple($_GET, $sql_details, $table, $primaryKey, $columns);
echo json_encode($result);
To use that trick, you also need to edit ssp.class.php and replace all instances of FROM `$table` with FROM $table to remove backticks.
Alternatively, there is github.com/emran/ssp repository for library that extends ssp.class.php allowing GROUP BY, JOIN, aliases.
LINKS
See jQuery DataTables: Using WHERE, JOIN and GROUP BY with ssp.class.php for more information.