How to fix the error in codeigniter project? - php

My error message in codeigniter framework:
A Database Error Occurred
Error Number: 1140
In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'hms.rooms.id'; this is incompatible with sql_mode=only_full_group_by
SELECT `rooms`.*, count(room_no) as total_rooms FROM `rooms` WHERE `room_type_id` = '10'
Filename: D:/Installed_Apps/OpenServer/OpenServer/domains/hms.loc/system/database/DB_driver.php
Line Number: 691
Why is there such an error and how to eliminate it? In what there can be a problem in the code?
In these functions, something is wrong or everything is normal?
function check_availability($check_in,$check_out,$adults,$kids,$room_type_id){
$query = '?date_from='.$check_in.'&date_to='.$check_out.'&adults='.$adults.'&kids='.$kids.'&room_type=';
$CI =& get_instance();
if($check_in==$check_out){
$check_out = date('Y-m-d', strtotime($check_out.'+ 1 day'));
}
$CI->db->where('id',1);
$settings = $CI->db->get('settings')->row_array();
$CI->db->where('id',$room_type_id);
$CI->db->select('room_types.*,base_price as price');
$room_type = $CI->db->get('room_types')->row_array();
//echo '<pre>'; print_r($room_type);die;
$CI->db->where('room_type_id',$room_type_id);
$CI->db->select('rooms.*,count(room_no) as total_rooms');
$rooms = $CI->db->get('rooms')->row_array();
$total_rooms = $rooms['total_rooms'];
//echo '<pre>'; print_r($rooms);die;
$begin = new DateTime($check_in);
$end = new DateTime($check_out);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);
foreach($period as $dt){
$date = $dt->format( "Y-m-d" );
$dayno = $dt->format( "N" );
$day = $dt->format( "D" );
$day = strtolower($day);
///echo $date;die;
//check for room block period
if($date >= $settings['room_block_start_date'] && $date <=$settings['room_block_end_date'])
{
$block_message = "Sorry.. No Room Available Between ".date('d/m/Y',strtotime($settings['room_block_start_date']))." to ".date('d/m/Y',strtotime($settings['room_block_end_date']))." ";
$CI->session->set_flashdata('error', $block_message);
redirect('');
}
$CI->db->where('O.room_type_id',$room_type_id);
$CI->db->where('R.date',$date);
$CI->db->select('R.*,');
$CI->db->join('orders O', 'O.id = R.order_id', 'LEFT');
$orders = $CI->db->get('rel_orders_prices R')->result_array();
//echo '<pre>'; print_r($orders);die;
//echo $total_rooms;die;
if($total_rooms > 0){
//echo count($orders);die;
if(count($orders) >= $total_rooms){
$CI->session->unset_userdata('booking_data');
$CI->session->unset_userdata('coupon_data');
$CI->session->set_flashdata('error', "Sorry.. This Dates Between Rooms Not Available Please Try With Another Date Or Room");
redirect('front/book/index'.$query);
}else{
continue; // continue loop
}
}else{
$CI->session->unset_userdata('booking_data');
$CI->session->unset_userdata('coupon_data');
$CI->session->set_flashdata('error', "Sorry.. This Dates Between Rooms Not Available Please Try With Another Date Or Room");
redirect('front/book/index'.$query);
}
}
return;
}
function check_availability_ajax($check_in,$check_out,$adults,$kids,$room_type_id){
$query = '?date_from='.$check_in.'&date_to='.$check_out.'&adults='.$adults.'&kids='.$kids.'&room_type=';
$CI =& get_instance();
if($check_in==$check_out){
$check_out = date('Y-m-d', strtotime($check_out.'+ 1 day'));
}
$CI->db->where('id',1);
$settings = $CI->db->get('settings')->row_array();
$CI->db->where('id',$room_type_id);
$CI->db->select('room_types.*,base_price as price');
$room_type = $CI->db->get('room_types')->row_array();
//echo '<pre>'; print_r($room_type);die;
$CI->db->where('room_type_id',$room_type_id);
$CI->db->select('rooms.*,count(room_no) as total_rooms');
$rooms = $CI->db->get('rooms')->row_array();
$total_rooms = $rooms['total_rooms'];
//echo '<pre>'; print_r($rooms);die;
$begin = new DateTime($check_in);
$end = new DateTime($check_out);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);
foreach($period as $dt){
$date = $dt->format( "Y-m-d" );
$dayno = $dt->format( "N" );
$day = $dt->format( "D" );
$day = strtolower($day);
if($date >= $settings['room_block_start_date'] && $date <=$settings['room_block_end_date'])
{
$block_message = "Sorry.. No Room Available Between ".date('d/m/Y',strtotime($settings['room_block_start_date']))." to ".date('d/m/Y',strtotime($settings['room_block_end_date']))." ";
return $block_message;
}
$CI->db->where('O.room_type_id',$room_type_id);
$CI->db->where('R.date',$date);
$CI->db->select('R.*,');
$CI->db->join('orders O', 'O.id = R.order_id', 'LEFT');
$orders = $CI->db->get('rel_orders_prices R')->result_array();
//echo $total_rooms;die;
if($total_rooms > 0){
if(count($orders) > $total_rooms){
$CI->session->unset_userdata('booking_data');
$CI->session->unset_userdata('coupon_data');
return 'Sorry.. This Dates Between Rooms Not Available Please Try With Another Date Or Room';
}else{
continue; // continue loop
}
}else{
$CI->session->unset_userdata('booking_data');
$CI->session->unset_userdata('coupon_data');
return 'Sorry.. This Dates Between Rooms Not Available Please Try With Another Date Or Room';
}
}
return 1;
}
Here is my Book.php controller code where I use that functions:
function index()
{
//echo '<pre>'; print_r($_GET);
//check availbilty
//get_invoice_number();
$this->session->unset_userdata('booking_data');
$this->session->unset_userdata('coupon_data');
$data['page_title'] = lang('make_reservation');
$data['meta_description'] = $this->setting->meta_description;
$data['meta_keywords'] = $this->setting->meta_keywords;
$data['banners'] = $this->homepage_model->get_banners();
$data['testimonials'] = $this->homepage_model->get_testimonials(); // get 6 testimonials
$data['room_types'] = $this->homepage_model->get_room_types_all();
$data['taxes'] = $this->homepage_model->get_taxes();
if(!empty($_GET['room_type'])){
$data['services'] = $this->homepage_model->get_paid_services($_GET['room_type']);
}
//echo '<pre>'; print_r($data['services']);
if(empty($_GET['room_type'])){
$this->render('book/room_types', $data);
}else{
check_availability($_GET['date_from'],$_GET['date_to'],$_GET['adults'],$_GET['kids'],$_GET['room_type']);
$data['room_type'] = $this->homepage_model->get_room_type($_GET['room_type']);
$this->render('book/view', $data);
}
}

you are facing this problem because of the ONLY_FULL_GROUP_BY option in the MYSQL so kindly set,
SET GLOBAL sql_mode=(SELECT REPLACE(##sql_mode,'ONLY_FULL_GROUP_BY',''));
to solve the issue.

SQL query including aggregate functions like COUNT() or SUM() etc. always have a GROUP BY clause in it. Which specifies the other non-grouped columns in the final resultset.
In you query the following remarks are noted:
You have specified rooms.* which is not recommended while grouping.
You may mention specific columns while grouping, and specify those columns in the GROUP BY clause too.
For example,
SELECT
Count(product_tb.product_id),
product_tb.`name`,
product_tb.details
FROM
`product_tb`
WHERE
product_tb.product_id = 1
GROUP BY
product_tb.`name`,
product_tb.details

Related

Codeigniter: No error but it won't insert data to database

Model:
function insertMonths($dr){
$cus = $this->db->query("SELECT * FROM purchase WHERE status=1 AND dr_no='$dr'");
return $cus->row();
$start = (new DateTime($cus->date_sold))->modify('+1 month');
$end = (new DateTime($cust->due_date))->modify('+1 month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
$query = $this->db->query("SELECT * FROM duedate WHERE dr_no='$dr'");
if($query->num_rows() > 0){
return false;
}else{
foreach ($period as $dt) {
$datas = array(
'cust_id' => $cust->cust_id ,
'mi' => $dt->format("Y-m-d") ,
'amount' => $cust->monthly_instlmnt,
'dr_no' => $dr,
'payment' => $cust->monthly_instlmnt
);
$this->db->insert('duedate', $datas);
}
}
}
Controller:
function ledger($id, $dr){
$this->load->view('layout/header');
$data['cust_data'] = $this->m->getData($id);
$datar['mos'] = $this->m->insertMonths($dr);
$this->load->view('receivables/ledger', $data, $datar);
$this->load->view('layout/footer');
}
Botton js code that links to ledger:
'<td><button type="button" class="btn btn-success">View</button></td>'
I want it to add $datas into table duedate when I enter link ledger/id/dr with conditions if there is duplicate data it won't add.
But the problem is it won't add eventhough there is no duplicate data.
Why do you have a return statement on line 2 of your function?
$cus = $this->db->query("SELECT * FROM purchase WHERE status=1 AND dr_no='$dr'");
return $cus->row();
If you neglected that, it won't go to your insert query since you already commanded the function to return.
Remove this (On line 2 of your function)
return $cus->row();

Calculate date before n days of a month

How to calculate a date before 10 days of every month end ?Am using codeigniter platform.
I need to check whether a date is within 10 days before the end of every month.
Please help
You can try using date_modify function for example see this php documentation
http://php.net/manual/en/datetime.modify.php
i need to check whether a date is within10 days before the end of a month
function testDate($date) {
$uDate = strtotime($date);
return date("m", $uDate) != date("m", strtotime("+10 days", $uDate));
}
echo testDate("2016-03-07") ? "Yes" :"No"; // No
echo testDate("2016-03-27") ? "Yes" :"No"; // Yes
you can create a library with this
class Calculate_days{
function __construct() {
parent::__construct();
}
function calculate( $to_day = date("j") ){
$days_month = date("t");
$result = (int) $days_month - $to_day;
if( $result <= 10){
$result = array("type" => TRUE, "missing" => $result . 'days');
return $result;
}
else{
$result = array("type" => FASLE, "missing" => $result . 'days');
return $result;
}
}
}
controller.php
function do_somthing(){
$this->load->library('Calculate_days');
$result = $this->Calculate_days->calculate(date("j"));
var_dump($result);
}

Laravel 5 ORM update request, like date_add

I beg to excuse me for my poor english.
So, I have Laravel 5 ORM, and i need to make request that should add date to some rows, like MySQL DATE_ADD. Input is single date interval and array of id's, output is rows of database, that was changed by adding date interval. Ideally, it should be one ORM request. I know that it is possible to use "bad" way and get all rows, update it in a code, and insert to database, but imho it's not good.
I hope answer will be link to some help site or some code if it's does not complicate you. Thanks for your attention!
public function update($id)
{
$user_id = Auth::user()->id;
$rep_task = RepTask::find($id);
$cl_task = \Request::has('json') ? json_decode(\Request::input('json'),true) : \Request::all();
$ids = [];
$task_id = $rep_task->task_id;
$rep_tasks = RepTask::where('task_id', '=', $task_id)
->select('id')
->get();
$new_date = date_create_from_format(self::DATE_FULLCALENDAR_FORMAT, $cl_task['new_date']);
$selected_task_date = date_create_from_format(self::DATE_MYSQL_FORMAT, $rep_task->start_date);
$diff = date_diff($selected_task_date, $new_date);
if(\Request::has('json'))
{
$ids = [1,2,3]; //this for easy understanding
DB::table('rep_task')
->whereIn('id', $ids)
->update(['start_date' => DB::raw('DATE_ADD(start_date, INTERVAL ' . $diff->d . ' DAY)')]);
$out_json = ['updated' => $ids];
return json_encode($out_json, JSON_UNESCAPED_UNICODE);
}
else
{
$start_date = 0;
$end_date = 0;
if (!isset($cl_task['name']) || !isset($cl_task['text']))
return "{'error':'columns are not defined'}";
if (isset($cl_task['start_date']) && isset($cl_task['end_date']))
{
$dt = date_create_from_format(self::DATE_FULLCALENDAR_FORMAT, $cl_task['start_date']);
$start_date = $dt->format(self::DATE_MYSQL_FORMAT);
$dt = date_create_from_format(self::DATE_FULLCALENDAR_FORMAT,$cl_task['end_date']);
$end_date = $dt->format(self::DATE_MYSQL_FORMAT);
}
$rep_task->name = $cl_task['name'];
$rep_task->text = $cl_task['text'];
$rep_task->start_date = $start_date;
$rep_task->end_date = $end_date;
$rep_task->users_id = $user_id;
$rep_task->save();
}
$user_id = Auth::user()->id;
$tasks = Task::getAllTasksByUserFullcalendar($user_id);
return view(
'task.index',
[
'tasks' => $tasks
]
);
}

How to search a CSV file with php by checking if a date falls between 2 ranges

I made a previous post that was too vague. I've done a lot of research and think I can be more specific.
while (!feof($file_handle))
{
$loansinfo = fgetcsv($file_handle);
// Make sure we only check data for the game we posted
if($loansinfo[0]==$ID) {
$referenceDate = $WantedDate;
$fromDate = "$loansinfo[5]";
$toDate = "$loansinfo[6]";
// Convert dates to timestamps (strings to integers)
$referenceTimestamp = strtotime( $referenceDate );
$fromTimestamp = strtotime( $fromDate );
$toTimestamp = strtotime( $toDate );
$isBetween = $referenceTimestamp >= $fromTimestamp and $referenceTimestamp <= $toTimestamp;
//refuse booking
echo('<script type="text/javascript">alert("Game Already Booked");</script>');
exit;
}
}
// otherwise execute save code
Problem is, I always get 'Game already booked'. Why?
Sample CSV file data as requested:
ID, GameName,GameCost, DaysRequested, Total, ReservationStart, DateEnd
5,Pinball, 3.99,7, 27.99, 01/01/2015, 08/01/2015
Though it should be said that the form requires date entry as YYYY-MM-DD. I have java script that does the conversion.
I've seen this one! Try this:
while (!feof($file_handle)) {
$loansinfo = fgetcsv($file_handle);
if($loansinfo[0]==$ID){
$FromDate = "$loansinfo[5]";
$ToDate ="$loansinfo[6]";
if (strtotime($DateBorrowedFrom) <= strtotime($WantedDate)) {
if(strtotime($ToDate) >= strtotime($WantedDate)){
$CantBook = True;
}
}
else {
if (strtotime($DateBorrowedFrom) <= strtotime($DateTo)) {
$CantBook= true;
}
}
}
}
fclose($file_handle);
if($CantBook = true){
echo('<script type="text/javascript">alert("Game is already Booked");</script>');
}
else{
//Saving the booking
From the look of your code, you are not checking the result of $isBetween.
Here is a modified version that will get you a lot closer, assuming your dates are formatted correctly.
while (!feof($file_handle))
{
$loansinfo = fgetcsv($file_handle);
// Make sure we only check data for the game we posted
if($loansinfo[0]==$ID) {
$referenceDate = $WantedDate;
$fromDate = "$loansinfo[5]";
$toDate = "$loansinfo[6]";
// Convert dates to timestamps (strings to integers)
$referenceTimestamp = strtotime( $referenceDate );
$fromTimestamp = strtotime( $fromDate );
$toTimestamp = strtotime( $toDate );
$isBetween = $referenceTimestamp >= $fromTimestamp and $referenceTimestamp <= $toTimestamp;
if($isBetween == true) {
//refuse booking
echo('<script type="text/javascript">alert("Game Already Booked");</script>');
exit;
}
}
}

How to refactor this conditional to avoid repetition?

This is part of an events page that can be filtered by date (using pre-defined date ranges or a date picker).
I want to avoid repeating the whole foreach ($days as $day_number)... etc. loop for every condition.
I guess that whole loop could be moved to a function, but I'm not sure how to implement it.
<?php
// open the db connection
$db = new wpdb('user', 'pass', 'db', 'server');
// $today = date('Y-m-d');
$today = '2009-06-21';
$tomorrow = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+1, date('Y')) );
$seven_days_ahead = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+6, date('Y')) );
$thirty_days_ahead = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+29, date('Y')) );
echo '<div class="column first">';
if ( ! empty($_REQUEST['date_range']) )
{
// user has chosen a date/range, show matching events
$date_range = mysql_real_escape_string($_REQUEST['date_range']);
switch( $date_range )
{
case 'all':
// code here
break;
case 'next_7_days':
// code here
break;
case 'next_30_days':
// code here
break;
default:
// code here
}
}
else
{
// no date selected, show todays events
$days = convert_date_to_day_number( $today );
foreach ( $days as $day_number )
{
$where = sprintf( 'WHERE e.day_id = %s', $day_number );
$events = get_events( $where );
if ($events)
{
echo '<table class="results">';
render_day( $day_number );
foreach ($events as $event)
{
render_event($event);
}
echo '</table>';
}
else
{
echo 'No events';
}
}
}
echo '</div> <!--/column-->';
function convert_date_to_day_number($date)
{
global $db;
$sql = "SELECT day_number FROM days WHERE day_date = '$date'";
$day_numbers = $db->get_results($sql);
foreach ($day_numbers as $key => $value)
{
$day_number[] = $value->day_number;
}
return $day_number;
}
function get_events($where)
{
global $db;
$sql = "SELECT
e.id,
TIME_FORMAT(e.start_time, '%H:%i' ) AS start_time,
e.x_prod_desc AS title,
-- e.title_en AS title,
p.name_en AS place,
et.name_en AS type,
w.week_number,
d.day_date AS start_date
FROM event AS e
LEFT JOIN place AS p ON p.id = e.place_id
LEFT JOIN event_type AS et ON et.id = e.event_type_id
LEFT JOIN days AS d ON d.id = e.day_id
LEFT JOIN week AS w ON w.id = d.week_id ";
$sql .= $where;
$events = $db->get_results($sql);
return $events;
}
function render_event($event)
{
$request_uri = $_SERVER['REQUEST_URI'];
$output = <<<EOD
<tr class="week-$event->week_number">
<td class="topic"></td>
<td class="time">$event->start_time</td>
<td class="summary">
$event->title
</td>
<td class="type">$event->type</td>
<td class="location">
<span class="addr">$event->place</span>
</td>
</tr>
EOD;
echo $output;
}
function render_day( $day_number )
{
global $db;
$sql = "SELECT
d.day_number,
DATE_FORMAT( d.day_date, '%W %e %M %Y' ) AS date,
DATE_FORMAT( d.day_date, '%b' ) AS month,
DATE_FORMAT( d.day_date, '%e' ) AS day
FROM days AS d
WHERE day_number = " . $day_number;
$day = $db->get_results($sql);
$day = $day[0];
$output = <<<EOD
<tr class="day">
<th colspan="5">
<em class="date">
<abbr class="dtstart" title="20090605T1806Z">
<span title="$day->date">
<span class="month">$day->month</span>
<span class="day">$day->day</span>
</span>
</abbr>
</em>
$day->date
<span class="event-day">Day $day->day_number</span>
</th>
</tr>
EOD;
echo $output;
}
?>
First, you may want to use strtotime for relative dates :
$today = '2009-06-21';
$tomorrow = date( 'Y-m-d', strtotime('+1 day') );
$seven_days_ahead = date( 'Y-m-d', strtotime('+7 days') );
$thirty_days_ahead = date( 'Y-m-d', strtotime('+30 day') );
// or +1 month (=> calendar month)
Second, you can set two variables with begin & end dates, then:
$date = $start_date; // 'Y-m-d' format
while( $date <= $end_date ) {
//code here or fill up a table with your days
// using $date
$date = date( 'Y-m-d', strtotime( '+1day', strtotime($date) ) );
}
Whenever working with dates in PHP, you should check strtotime.
Rather than querying the database once for every day, I would make a WHERE statement that fetched all events for the desired date range, and then send that to a render function which loops through every row in the result set and if the day is different from previous one, calls render_day() before calling render_event().
switch (/* input from user */) {
// Build a date range here.
// Resulting statement would be something like:
// WHERE event_date >= '2009-06-10' AND event_date < '2009-06-17'
}
$events = get_events($filter);
$prev_date = null;
foreach ($events as $event) {
if ($event->date != $prev_date) render_day($event->date);
render_event($event);
$prev_date = $event->date;
}
function generateEventsTable($dateStr)
{
$days = convert_date_to_day_number( $today );
foreach ( $days as $day_number )
{
$where = sprintf( 'WHERE e.day_id = %s', $day_number );
$events = get_events( $where );
if ($events)
{
echo '<table class="results">';
render_day( $day_number );
foreach ($events as $event)
{
render_event($event);
}
echo '</table>';
}
else
{
echo 'No events';
}
}
}
Call it like this:
generateEventsTable($today);
Wow! I've read it!
First of all use template engine (like smarty) or any other way to split your code and HTML. That's a bad idea to echo HTML from inside the functions.
I'm not sure but I think that using unix-timestamps in DB could simplify your data structure. The same is about php code. Read carefully about date/time functions in php manual, I think, you'll find a lot of interesting things...
Actually, as I see from your code using timestamps and templates will reduce your code to some line for fetching data and assigning it to template engine. PHP's "date()" function already has an option to return week numbe, day number in a week or in a year etc...
This is dummy exaple what could your code look like:
$begin = mktime(...);
$end = mktime(...);
$query = "
SELECT a,b,c
FROM events
WHERE ctime >= $begin AND ctime <= $end AND ...
";
$events = array();
while ($fetch = fetch_here(...))
{
$event = new MyEvent();
$event->loadDBFetch($fetch);
array_push($events, $event);
}
$tplEngine->assign('events', $events);
Sure, this is not a ready-to-go solution, but it seems to me, that your code could be similar to this.

Categories