draw datatable is null when i use where in my query - mysql

I have some problem with showing data in datatable, the problem is when I using the query clause like where condition, the draw in datatable is had a null value but when I'm not using the where condition, the data will be display on my datatable, is anything wrong with my query in codeigniter?
model :
var $attendance = 'attendance';
var $employee = 'employee';
var $project = 'project';
var $column = [
null, 'attendance.no_reg', 'employee.name', 'project.project_name', 'project.project_code'
];
var $column_search = [
'attendance.no_reg', 'employee.name', 'project.project_name', 'project.project_code'
];
var $column_order = [
null, 'attendance.no_reg', 'employee.name', 'project.project_name', 'project.project_code'
];
private function _showDaily() {
$selectedValues = $this->input->post('selectedValues');
$this->db->select($this->column);
$this->db->from($this->attendance);
// $this->db->where("project_code", $selectedValues);
$this->db->join($this->employee, "attendance.no_reg = employee.no_reg");
$this->db->join($this->project, "attendance.project_id = project.id");
$this->db->group_by("attendance.no_reg");
// length table
$i = 0;
foreach ($this->column_search as $item) // initial looping for grouping insert a text search
{
error_reporting(0);
if ($_POST['search']['value']) { // if the datatable make a input search with POST method
if ($i === 0) { // initial first condition for first column
$this->db->group_start();
$this->db->like($item, $_POST['search']['value']);
} else {
$this->db->or_like($item, $_POST['search']['value']);
}
if (count($this->column_search) - 1 == $i) // condition if the text search value counting same with $i value then minus 1
$this->db->group_end();
}
$i++;
}
if (isset($_POST['order'])) {
$this->db->order_by($this->column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
}
}
public function showsDaily()
{
$this->_showDaily();
$result = $this->db->get();
return $result->result();
}
If my explanation is incomprehensible, I apologize, and you can ask me again, Thank You

Related

Laravel Query builder returns a row from join instead of multiples row

I am getting fewer results than expected , The data returns 57 rows instead of 70 rows. I need help to get all the rows please, I returned a collection using get(), and i joined it with foreach() to include the rows to existing query, Please any help?
public function getempAttendance(Request $request) {
$id = $request->id;
$department_id = $request->department_id;
if($id !== null){ //return based on type;
$emp = AsEmployee::where('id','=',$id)->orderBy('id','ASC')->get();
} else if($department_id != null){
$emp = AsEmployee::where('department_id','=',$department_id)->orderBy('id','ASC')->get();
} else{ //return all if nothing is given;
$emp = AsEmployee::orderBy('id','DESC')->get();
}
foreach($emp as $emp_data){
$department = AsDepartment::where('id','=',$emp_data->department_id)->get(['department'])->first();
if($department !== NULL){
$emp_data->department_name = $department->department;
}else{
$emp_data->department_name = '';
}
$position = AsEmployeePosition::where('id','=',$emp_data->position_id)->get(['position_name'])->first();
if($position !== NULL){
$emp_data->position_name = $position->position_name;
}else{
$emp_data->position_name = '';
}
$attendances = AsAttendanceLog::select('CHECK_IN_TIME','CHECK_OUT_TIME')
->where('EMPLOYEE_ID','=',$emp_data->employee_id)->get();
if($attendances !== NULL){
foreach($attendances as $attendance){
$emp_data->CHECK_IN_TIME = Carbon::parse($attendance->CHECK_IN_TIME)->toTimeString();
$emp_data->CHECK_OUT_TIME = Carbon::parse($attendance->CHECK_OUT_TIME)->toTimeString();
$emp_data->Date = Carbon::parse($attendance->CHECK_IN_TIME)->format('Y-m-d');
$hours = Carbon::parse($attendance->CHECK_OUT_TIME)->diffInSeconds(Carbon::parse($attendance->CHECK_IN_TIME));
$emp_data->Hours = gmdate('H:i', $hours);
}
}else {
$emp_data->CHECK_IN_TIME = '';
$emp_data->CHECK_OUT_TIME = '';
}
}
return $this->sendResponse($emp);
}
Meanwhile, this works but i need the query builder format to allow me use Carbon and do some operations
$attendanceData = DB::table('as_tbl_employee_master AS emp')
->leftJoin('as_tbl_department AS dept','emp.department_id','=', 'dept.id')
->leftJoin('as_tbl_employee_position AS pos', 'emp.position_id', '=', 'pos.id')
->leftJoin('as_tbl_emp_attendance_daily_log AS att', 'att.EMPLOYEE_ID', '=', 'emp.employee_id')
->select('emp.id','emp.employee_id','emp.english_name','dept.department','pos.position_name','att.CHECK_IN_TIME','att.CHECK_OUT_TIME')
->orderby('att.CHECK_IN_TIME', 'DESC')
->get();
return $this->sendResponse($attendanceData);
if the user's table is "one to many" to as_tbl_emp_attendance_daily_log's table.
You should select('as_tbl_emp_attendance_daily_log') first then left join to user's table.
I assumed that you want to show all as_tbl_emp_attendance_daily_log's row. If that right your Query builder should be like this.
$attendanceData = DB::table('as_tbl_emp_attendance_daily_log AS att')
->leftJoin('as_tbl_employee_master AS emp', 'att.EMPLOYEE_ID', '=', 'emp.employee_id')
->leftJoin('as_tbl_department AS dept','emp.department_id','=', 'dept.id')
->leftJoin('as_tbl_employee_position AS pos', 'emp.position_id', '=', 'pos.id')
->select('emp.id','emp.employee_id','emp.english_name','dept.department','pos.position_name','att.CHECK_IN_TIME','att.CHECK_OUT_TIME')
->orderby('att.CHECK_IN_TIME', 'DESC')
->get();
UPDATE
If you want to add the custom attribute to the model you should define it at the model.
This is for reference:
https://laravel.com/docs/5.1/eloquent-serialization#appending-values-to-json
But you can directly change the attribute if you change the collections to the array first.
I don't have your table, so I cannot test it, I just changed it based on your snippet.
public function getempAttendance(Request $request) {
$id = $request->id;
$department_id = $request->department_id;
if($id !== null){ //return based on type;
$emp = AsEmployee::where('id','=',$id)->orderBy('id','ASC')->toArray();
} else if($department_id != null){
$emp = AsEmployee::where('department_id','=',$department_id)->orderBy('id','ASC')->toArray();
} else{ //return all if nothing is given;
$emp = AsEmployee::orderBy('id','DESC')->toArray();
}
for($i=0;$i < count($emp); $i++){
$department = AsDepartment::where('id','=',$emp[$i]->department_id)->get(['department'])->first();
if($department !== NULL){
$emp[$i]['department_name'] = $department->department;
}else{
$emp[$i]['department_name'] = '';
}
$position = AsEmployeePosition::where('id','=',$emp[$i]['position_id'])->get(['position_name'])->first();
if($position !== NULL){
$emp[$i]['position_name'] = $position->position_name;
}else{
$emp[$i]['position_name'] = '';
}
$attendances = AsAttendanceLog::select('CHECK_IN_TIME','CHECK_OUT_TIME')
->where('EMPLOYEE_ID','=',$emp[$i]['employee_id'])->toArray();
$attendances_data = [];
if($attendances !== NULL){
for($j=0;$j<count($attendances);$j++){
$data = [];
$data['CHECK_IN_TIME'] = Carbon::parse($attendance['i']['CHECK_IN_TIME'])->toTimeString();
$data['CHECK_OUT_TIME'] = Carbon::parse($attendance['i']['CHECK_OUT_TIME'])->toTimeString();
$data['Date'] = Carbon::parse($attendance['i']['CHECK_IN_TIME'])->format('Y-m-d');
$hours = Carbon::parse($attendance['i']['CHECK_OUT_TIME'])->diffInSeconds(Carbon::parse($attendance['i']['CHECK_IN_TIME']));
$data['Hours'] = gmdate('H:i', $hours);
$attendances_data[] = $data
}
$emp[$i]['attendances'] = $attendances_data;
}else {
$emp[$i]['attendances'] = [];
$emp[$i]['attendances'] = [];
}
}
return $this->sendResponse($emp);
}
UPDATE
If you want to multiple row, I think you should try this:
$attendanceData = DB::table('as_tbl_emp_attendance_daily_log AS att')
->leftJoin('as_tbl_employee_master AS emp', 'att.EMPLOYEE_ID', '=', 'emp.employee_id')
->leftJoin('as_tbl_department AS dept','emp.department_id','=', 'dept.id')
->leftJoin('as_tbl_employee_position AS pos', 'emp.position_id', '=', 'pos.id')
->select('emp.id','emp.employee_id','emp.english_name','dept.department','pos.position_name','att.CHECK_IN_TIME','att.CHECK_OUT_TIME')
->orderby('att.CHECK_IN_TIME', 'DESC')
->toArray();
for($i=0;$i<count($attendaceData);$i++)
{
$attendaceData[$i]['CUSTOM VARIABLE'] = 'NEW VALUE CUSTOM VARIABLE AT HERE';
}
return $this->sendResponse($emp);

Mysql Left Join DataTable Serverside Codeigniter

Can you help me on this?
No tables used
SELECT * ORDER BY id asc LIMIT 0
This is my sql code on the model
private function _get_datatables_query()
{
$this->db->query("SELECT mainproduk.id,
mainproduk.barcode as barcod,
mainproduk.nama_produk,
mainproduk.nama_alias,
mainproduk.satuan,
mainproduk.produk_jadi,
mainproduk.kemasan,
mainproduk.min_stok_kemasan,
mainproduk.status,
mainproduk.top_item,
mainproduk.tipe_produk,
mainproduk.nomor_kemtan,
coalesce(sum(R.jumlah_pc),0) as omzet
FROM mainproduk
LEFT JOIN
(
SELECT id,barcode, jumlah_pc
FROM rincian_order WHERE tipe='po' AND status!='canceled' AND tanggal_kirim BETWEEN '$kemarins' AND '$blnkemarin'
) AS R
ON mainproduk.barcode = R.barcode WHERE status=1 GROUP BY mainproduk.id ORDER BY mainproduk.id ASC");
$i = 0;
foreach ($this->column_search as $item) // loop column
{
if($_POST['search']['value']) // if datatable send POST for search
{
if($i===0) // first loop
{
$this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
$this->db->like($item, $_POST['search']['value']);
}
else
{
$this->db->or_like($item, $_POST['search']['value']);
}
if(count($this->column_search) - 1 == $i) //last loop
$this->db->group_end(); //close bracket
}
$i++;
}
if(isset($_POST['order'])) // here order processing
{
$this->db->order_by($this->column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
}
else if(isset($this->order))
{
$order = $this->order;
$this->db->order_by(key($order), $order[key($order)]);
}
}
When I use the above method will appear no table problem is used, because the recording is off.
then I change it with the active record like below and there is an error that seems "COALESCE" does not support in such format, then if "coalesce (sum (details_order.jumlah_pc), 0) as omzet" I delete it will appear error as below this
private function _get_datatables_query()
{
$this->db->select('mainproduk.barcode as barcod, mainproduk.nama_produk, mainproduk.nama_alias, mainproduk.satuan, mainproduk.produk_jadi, mainproduk.kemasan, mainproduk.min_stok_kemasan, mainproduk.status, mainproduk.top_item, mainproduk.tipe_produk, mainproduk.nomor_kemtan, coalesce(sum(rincian_order.jumlah_pc),0) as omzet')
->from('mainproduk')
->join('rincian_order', 'mainproduk.barcode = rincian_order.barcode', 'left')
->where('mainproduk.status =', 1)
->group_by('mainproduk.id')
->order_by('mainproduk.id', 'ASC');
$i = 0;
foreach ($this->column_search as $item) // loop column
{
if($_POST['search']['value']) // if datatable send POST for search
{
if($i===0) // first loop
{
$this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
$this->db->like($item, $_POST['search']['value']);
}
else
{
$this->db->or_like($item, $_POST['search']['value']);
}
if(count($this->column_search) - 1 == $i) //last loop
$this->db->group_end(); //close bracket
}
$i++;
}
if(isset($_POST['order'])) // here order processing
{
$this->db->order_by($this->column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
}
else if(isset($this->order))
{
$order = $this->order;
$this->db->order_by(key($order), $order[key($order)]);
}
}
Column 'id' in order clause is ambiguous
Please help
`mainproduk.id`
`mainproduk.barcode`
similarly to other fields
try writing this as your syntax.
if that doesn't work can you print_r the query ?

Yii2 ActiveRecord add a new record with unique text field

I am using Yii2 and ActiveRecord. I have a field called "code" and for each record, it is meant to have a unique value like this: "REC0001", "REC0002", "REC0003" in a sequencial manner.
All works and I can generate a record code as described. However if I refresh my page request fast in a multiple manner (trying to test multiple requests at the same time in a very raw manner hehe), then some of the records end up with the same record code. In other words I found "REC007" a few times.
I generate the code looking at the last code and increase it by one, then I do a while foundFlag == true by checking to see if it already exists in the database.
I am suspecting there is a delay in writing to the database and hence it assumes that it is not there.
Here is a portion of the code:
static function createCode($rec){
if ($rec->code){
return $rec->code;
}
if ($rec->id){ // find it by id if one passed and record exists
$tmpRec = $rec->find()
->where([
'id' => $rec->id,
])
->one();
if ($tmpRec && $tmpRec->code){
return $tmpRec->code;
}
}
$prefix = 'REC';
if (!$prefix){
$prefix = 'REC';
}
$maxDecimals = 12;
$codeLength = $maxDecimals+strlen($prefix);
$query = $rec->find();
$query = $query->where([
'archived' => '0'
]);
// look under an organization if it exists in the model and there is one
if ($rec->hasField('organization_id') && $organization_id){
$query = addQueryWhere($query, [
'organization_id' => $organization_id,
]);
}
$query = addQueryWhere($query, [
'LENGTH(code)' => $codeLength*1,
]);
$query = $query->orderBy('code desc');
$lastRec = $query->one();
$tmpNumber = 0;
if ($lastRec && $lastRec->id){
// check what it returns
$tmpNumber = str_replace($prefix, '', $lastRec->code);
}
$tmpNumber++;
$leftDecimals = $maxDecimals - strlen($tmpNumber.'');
for ($k=0; $k <= $leftDecimals-1 ; $k++){
$tmpNumber = '0'. $tmpNumber;
}
$ret = $prefix . $tmpNumber;
return $ret;
}
public function generateCode($rec){
$foundFlag = true;
$break = 1000; // safe break point - no continuous loop
$cnt = 0;
$code = static::createCode($rec);
while ($foundFlag === true || $cnt < $break){
$tmpRec = $rec->find()
->where([
'code' => $code,
])
->one();
if (!$tmpRec->id){
$foundFlag = false;
break;
}
$time = getCurrentTimestamp();
$code = static::createCode($rec);
$cnt++;
}
$ret = $code;
return $ret;
}
So I simply call: $this->code = $this->generateCode();
Like I said it does work in generating the code, but it creates duplicates when it shouldn't!
Thank you for your assistance.

Get data into array using mysql prepared statements

I'm trying to get the function below to return an array of user_ids. Here is the function in php.
function users_following($follower_id)
{
include "dbconn.php";
$stmt = mysqli_prepare($con, "SELECT user_id FROM follo WHERE follower_id = ?");
mysqli_stmt_bind_param($stmt, "i", $follower_id);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $following_user_id);
$count = 0;
$user_array = array();
while (mysqli_stmt_fetch($stmt) ) {
$user_array[] = $following_user_id;
$count = $count + 1;
}
mysqli_stmt_close($stmt);
if ($count > 0)
{
return $user_array;
} else {
return false;
}
}
The problem is that the above function just returns the output: 'Array' (without quotes), when I tested with the code below, not the list of user_ids.
$userid_array = users_following($_SESSION["user_id"]);
echo $userid_array;
Can anyone please help me out? If you need additional details, just comment below and I will try to clarify.

How to modify and change data in ng-grid

I have the following code:
var app = angular.module('mcmmo', ['ngGrid']);
app.controller('mcmmoCtrl', function($scope, $http) {
$scope.filterOptions = {
filterText: "",
useExternalFilter: true
};
$scope.totalServerItems = 0;
$scope.pagingOptions = {
pageSizes: [250, 500, 1000],
pageSize: 250,
currentPage: 1
};
$scope.setPagingData = function(data, page, pageSize){
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.myData = pagedData;
$scope.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('stats.php').success(function (largeLoad) {
data = largeLoad.filter(function(item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data,page,pageSize);
});
} else {
$http.get('stats.php').success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
}
}, 100);
};
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.$watch('pagingOptions', function (newVal, oldVal) {
if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.$watch('filterOptions', function (newVal, oldVal) {
if (newVal !== oldVal) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
showFooter: true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions,
plugins: [new ngGridFlexibleHeightPlugin()]
};
});
Which pulls a very large load of JSON from a php file, that's stored in a database. Here are my json results.
[{"id":"1","user":"user1","lastlogin":"1402936307","skills":[{"taming":"4","mining":"534","woodcutting":"84","repair":"26","unarmed":"0","herbalism":"108","excavation":"219","archery":"10","swords":"75","axes":"24","acrobatics":"74","fishing":"403","alchemy":"0"}]
}
Here is the PHP that outputs this:
require_once('db.php');
error_reporting(1);
$getUsers = mysqli_query($db, 'SELECT * FROM mcmmo_users LIMIT 300');
$rows = array();
while ($r = mysqli_fetch_assoc($getUsers))
{
$skills = array();
$tempRow = $r;
$getSkills = mysqli_query($db, "SELECT * FROM mcmmo_skills WHERE user_id = '" . $r['id'] . "' LIMIT 300");
while ($r = mysqli_fetch_assoc($getSkills))
{
unset($r['user_id']);
$skills[] = $r;
}
$tempRow['skills'] = $skills;
$rows[] = $tempRow;
}
header('Content-Type: application/json');
echo json_encode($rows);
And this is what my grid currently looks like:
There is a couple of things wrong here:
I don't want the id or lastlogin columns.
I'd like to rename "users".
Instead of the "skills" column, I'd like for all of the data to be in it's own column, for example, taming and mining is it's own column with it's data in it's own row.
I'm not sure how to do that with this plugin though, any help would be appreciated!
Well, maybe changing the query string would be easy to handle it. Also by the time you navigate inside the query result, you can build your own array, just use an array with key as the name of the column.
$getUsers = mysqli_query($db, 'SELECT * FROM mcmmo_users LEFT JOIN mcmmo_skills ON mcmmo_users.id = mcmmo_skills.user_id');
$rows = array();
$cont = 0;
$userSkills = array();
while ($r = mysqli_fetch_assoc($getUsers))
{
$userSkills[$cont++] = array(
"Users" => $r['user'],
"Taming" => $r["taming"],
"Mining" => $r["mining"]
);
}
header('Content-Type: application/json');
echo json_encode($userSkills);
About Pagination
Try dirPagination at https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
It's very simple to use it and saves a lot of time.
As one of the commenters has already suggested, you can specify different column definitions than you have received in your incoming data. When you define your grid options, you optionally specify the column definitions separately from the data displayed:
$scope.resultGridOptions = {
data: 'myData',
columnDefs: 'columndefs',
// other parameters....
Then you just need to define your columns to reference your incoming data as documented here (especially the field and displayName):
https://github.com/angular-ui/ng-grid/wiki/Defining-columns
In your case, something like
$scope.columndefs = [{field:'id', displayName:'Id'}, {field:'user', displayName:'User'}];
should only show the id and user columns with the headers Id and User. (unless I have a typo)
Just noticed the final column part of your question: I am not sure how to show so much information in the final column. ng-grid does not support variable grid height to my knowledge, so it would make it difficult unless you can figure out a way to really condense this information into a column, but I don't know enough about your domain to recommend anything that seems reasonable.