Get the last message postgres - sql

I'm using Laravel to build something like a chat, i'd like to get the last message from user X and Y:
I have this table called "messages"
id integer
receiver_id integer references user
sender_id integer references user
message text
created_at datetime
Here I have a the message, when and who send the message;
$user = JWTAuth::toUser();
$messages = DB::table("messages")
->select(DB::raw(
"least(sender_id, receiver_id) as user_1,
greatest(sender_id, receiver_id) as user_2,
max(created_at) as last_timestamp,
max(message) as message"))
->where("sender_id", $user->id)
->orWhere("receiver_id", $user->id)
->groupBy(DB::raw("least(sender_id, receiver_id), greatest(sender_id, receiver_id)"))
->orderBy("last_timestamp", "desc")
->get();
$message_info = array();
foreach($messages as $k => $m) {
$message_info[$k]['message'] = $m->message;
$message_info[$k]['last_message'] = $m->last_timestamp;
if($m->user_2 == $user->id){
$message_info[$k]['user_id'] = $m->user_1;
}else{
$message_info[$k]['user_id'] = $m->user_2;
}
}
Here I list the users that have messages
$listUserHaveMessage = [];
foreach ($messages as $message){
if($message->user_2 == $user->id){
$listUserHaveMessage[] = $message->user_1;
}else{
$listUserHaveMessage[] = $message->user_2;
}
}
And here the users that not have send messages
$notMessage = User::where("client_id",'=',$user->client_id)
->where("id","!=", $user->id)
->where("is_visible",'=', true)
->whereNotIn("id", $listUserHaveMessage)
->get();
foreach ($notMessage as $m){
$listUserNotHaveMessage[] = $m->id;
}
Now I make the merge of arrays and a query to get all users
$list_users = array_merge($listUserHaveMessage, $listUserNotHaveMessage);
$idsImploded = implode(',',$list_users);
$users = User::where("client_id",'=',$user->client_id)
->where("id","!=", $user->id)
->where("is_visible",'=', true)
->whereIn("id", $list_users)
->orderByRaw(DB::raw("position(id::text in '$idsImploded')"))
->get();
$outPut = array();
foreach($users as $k => $u){
$outPut['usuarios'][$k] = $u;
}
My question is:
How to merge the last message to User array??
There is a way to do it??
Thanks

Related

Unable to insert id of user to another table laravel 8 livewire

I am unable to store user id of another user on my db. I have a messages table, where from_id,t_id and user_id are the foreign key of table users. I have models defined properly as well. The issue I am having is:
can't insert the user_id.
I can save everything else. when i do dd $this->id it shows the corret user id but when it comes to save them i can't.
I tried doing explode and it stopped showing those random values. it now gets the id however in below format: [{"id":3}]
: Invalid text representation: 7 ERROR: invalid input syntax for type bigint: "[{"id":3}]"
As you can see it's getting the user id when i get the values from authenticated user which is obvious.
My code :
public $messages, $sender;
public $users;
public $avatar;
protected $destination = '';
public $messageText;
public function mount($id)
{
$this->id = $id;
$this->avatar = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.id')
->where('users.id', '=', $this->id)->distinct()->get();
$this->destination = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.id')
->where('users.id', '=', $this->id)->first();
$this->users =
Message::latest()
->take(5)
->get()
->sortBy('id');
$this->messages = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.name', 'users.id', 'messages.message', 'messages.created_at')
->where('users.id', '=', $this->id)
->get();
// SELECT * FROM users AS u INNER JOIN messages AS m ON u.ID IN (m.senderID, m.recipientID) WHERE u.ID <> $userID GROUP BY u.ID ORDER BY m.sentAt DESC
}
public function render()
{
// $name = explode(' ', $this->avatar);
// dd($name);
return view(
'livewire.show',
[
'avatar' => $this->avatar,
'messages' => $this->messages,
'users' => $this->users,
]
)->layout('layouts.app');
}
public function sendMessage()
{
$name = explode(' ', $this->avatar);
// $this->validate(['messageText' => "required"]);
$message = new Message();
$message->from_id = Auth::user()->id;
$message->user_id = Auth::user()->id;
$message->to_id = $name[0]; // [{"id":3}]
$message->message = $this->messageText;
// dd($message);
$message->save();
$this->reset('messageText');
}
Error Message:

get table rate shipping data in Woocommerce REST API

I am trying to get all active shipping methods in Woocommerce REST API. How can I achieve this. I am new to woocommerce REST API, Any help is much appreciated.
I want response something like this -
{
"shipping_methods": {
"method_id": "method_title"
}
}
I , finally, come up with the solution. It may help others.
Below is complete code to get all table rate shipping data including shipping zones, shipping methods by zone and rates by zone -
header('Content-type: application/json');
$json_file=file_get_contents('php://input');
$jsonvalue= json_decode($json_file,true);
global $wpdb;
global $woocommerce;
$active_methods = array();
$shipping_methods = $woocommerce->shipping->load_shipping_methods();
//echo "<pre>";print_r($shipping_methods);
foreach ( $shipping_methods as $id => $shipping_method ) {
if ( isset( $shipping_method->enabled ) && 'yes' === $shipping_method->enabled ) {
$data_arr = array( 'title' => $shipping_method->title, 'tax_status' => $shipping_method->tax_status );
if($id=='table_rate'){
$raw_zones = $wpdb->get_results("SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones order by zone_order ASC;");
//echo "<pre>";print_r($raw_zones);
$shipping = array();
$shippingarr = array();
foreach ($raw_zones as $raw_zone) {
$zones = new WC_Shipping_Zone($raw_zone->zone_id);
$zone_id = $zones->zone_id;
$zone_name = $zones->zone_name;
$zone_enabled = $zones->zone_enabled;
$zone_type = $zones->zone_type;
$zone_order = $zones->zone_order;
$shipping['zone_id'] = $zone_id;
$shipping['zone_name'] = $zone_name;
$shipping['zone_enabled'] = $zone_enabled;
$shipping['zone_type'] = $zone_type;
$shipping['zone_order'] = $zone_order;
$shipping_methods = $zones->shipping_methods;
foreach($shipping_methods as $shipping_method){
$methodid = $shipping_method["number"];
$raw_rates[$methodid]['rates'] = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}woocommerce_shipping_table_rates WHERE shipping_method_id={$methodid};",ARRAY_A);
}
$shipping['shipping_methods'] = $raw_rates;
$raw_country = $wpdb->get_results("SELECT location_code FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE zone_id={$zone_id};",ARRAY_N);
$shipping['countries'] = $raw_country;
$shippingarr[] = $shipping;
}
$data_arr['shipping_zones'] = $shippingarr;
}
$active_methods[ $id ] = $data_arr;
}
}
if(!empty($shippingarr)){
$result['success']='true';
$result['error']="0";
$result['msg']='Shipping methos found.';
$result['data']=$active_methods;
}else{
$result['success']='true';
$result['error']="0";
$result['msg']='Shipping methos found.';
$result['data']= array();
}
echo json_encode($result); `

get values between two dates in silverstripe

i have added two date fields. i want to retrieve the data between those two table.PaymentDate and ChequePostedDate are two fields. so i need to get the rows between two dates.
simply search content have two date fields. i want to retrieve the rows(data) between those two dates
public function __construct($modelClass, $fields = null, $filters = null) {
$fields = new FieldList(array(
DateField::create('PaymentDate','Payment Date : from')
->setConfig('dateformat', 'yyyy-MM-dd')
->setConfig('showcalendar', true)
->setAttribute('placeholder','YYYY-MM-DD')
->setDescription(sprintf(
_t('FormField.Example', 'e.g. %s', 'Example format'),
Convert::raw2xml(Zend_Date::now()->toString('yyyy-MM-dd'))
)),
DateField::create('ChequePostedDate','cr Date : to')
->setConfig('dateformat', 'yyyy-MM-dd')
->setConfig('showcalendar', true)
->setAttribute('placeholder','YYYY-MM-DD')
->setDescription(sprintf(
_t('FormField.Example', 'e.g. %s', 'Example format'),
Convert::raw2xml(Zend_Date::now()->toString('yyyy-MM-dd'))
)),
));
$filters = array(
'PaymentDate' => new PartialMatchFilter('PaymentDate'),
'ChequePostedDate' => new PartialMatchFilter('ChequePostedDate'),
);
parent::__construct($modelClass, $fields, $filters);
}
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
$dataList = parent::getQuery($searchParams, $sort, $limit, $existingQuery);
$params = is_object($searchParams) ? $searchParams->getVars() : $searchParams;
$query = $dataList->dataQuery();
if(!is_object($searchParams)) {
if (isset($params['PaymentDate'])&& $params['ChequePostedDate'] ) {
$query->where('`PaymentNote`.PaymentDate BETWEEN \''.$params['PaymentDate'].' \' AND \''.$params['ChequePostedDate'].'\'');
}
}
return $dataList->setDataQuery($query);
}
}
You can also use WithinRangeFilter something like the following, but you need to use the setMin(), setMax() methods as per this forum response: https://www.silverstripe.org/community/forums/form-questions/show/11685
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
$dataList = parent::getQuery($searchParams, $sort, $limit, $existingQuery);
$params = is_object($searchParams) ? $searchParams->getVars() : $searchParams;
$query = $dataList->dataQuery();
if(!is_object($searchParams)) {
if (!empty($params['PaymentDate'] && !empty($params['ChequePostedDate'])) {
return $dataList->filter('PaymentDate:WithinRange', [$params['PaymentDate'], $params['ChequePostedDate']]);
}
}
return $dataList;
}
i solved it..
simply remove $filters
$filters = array(
// 'PaymentDate' => new PartialMatchFilter('PaymentDate'),
//'ChequePostedDate' => new PartialMatchFilter('ChequePostedDate'),
);
then it works

CDbCriteria throwing column name is ambigous

I have the following method in a controller of my Yii app.
public function actionManage($typeid=0, $locationid=0, $page=1, $rows=12, $sidx='date_input', $sord='desc', $kategori='')
{
if (Yii::app()->request->isAjaxRequest) {
// Jika dilakukan operasi 'edit' pada row
if (isset($_REQUEST['oper']))
{
$oper = $_REQUEST['oper'];
$id = $_REQUEST['id'];
if ($oper == 'edit')
{
$value = $_REQUEST['value'];
$record = InputData::model()->findByPk($id);
$record->value = $value;
$record->update();
}
if($oper == 'delete'){
$model = InputData::model()->findByPk($id);
$model->delete();
}
}
// inisialisasi criteria query
$criteria = new CDbCriteria();
$criteria->order = "$sidx $sord";
// filter lokasi
if (is_numeric($locationid) && $locationid !== 0)
{
$criteria->with = array('data'=>array(
'condition'=>'data.locationid=:locationid',
'params'=>array(':locationid'=>$locationid)
));
} else {
if (is_numeric($typeid) && $typeid !== 0)
{
$criteria->with = array('data.location'=>array(
'with'=>array(
'type'=>array(
'condition'=>'type.typeid=:typeid',
'params'=>array(':typeid'=>$typeid)
)
)
));
} else {
$criteria->with = array('data.location'=>array(
'with'=>array(
'type'=>array(
'condition'=>'type.type_desc=:type_desc',
'params'=>array(':type_desc'=>$kategori)
)
)
));
}
}
// filter range tanggal
if (isset($_REQUEST['startdate'], $_REQUEST['enddate']))
{
$startdate = $_REQUEST['startdate'];
$enddate = $_REQUEST['enddate'];
$criteria->condition = 'date_input <= :enddate AND date_input >= :startdate';
$criteria->params = array(':startdate'=>$startdate, ':enddate'=>$enddate);
}
if(isset($_REQUEST['dataid'])){
$dataid = $_REQUEST['dataid'];
$criteria->addCondition("dataid = $dataid");
}
$dataProvider = new CActiveDataProvider('InputData', array(
'criteria'=>$criteria,
'pagination'=>array(
'currentPage'=>$page-1,
'pageSize'=>$rows
)
));
$count = $dataProvider->totalItemCount;
$total_pages = $count > 0 ? ceil($count/$rows) : 0;
if ($page > $total_pages) $page=$total_pages;
// generate response untuk jqgrid
$response = new stdClass();
$response->page = $page;
$response->total = $total_pages;
$response->records = $count;
foreach($dataProvider->getData() as $row)
{
$response->rows[] = array(
'id'=>$row->inputdataid,
'cell'=>array(
$row->inputdataid,
$row->date_input,
$row->time_input,
$row->data->location->location_name,
$row->data->data_name,
$row->data->variable->var_name,
round($row->value, 3),
$row->data->variable->unit->uom_name,
($row->inputOfficer !== NULL ? $row->inputOfficer->officer_name:''),
'<i class="fa fa-pencil-square-o"></i> Edit <i class="fa fa-trash-o"></i> Delete'
)
);
}
echo json_encode($response);
} else {
$url = $this->createUrl("dataAir/manage");
$delurl = $this->createUrl("dataAir/deleteRow");
$startdate = '2013-01-01';
$enddate = date_format(new DateTime(), 'Y-m-d');
$this->render('jqgrid', array(
'kategori'=>$kategori,
'url'=>$url,
'delurl'=>$delurl,
'startdate'=>$startdate,
'enddate'=>$enddate
));
}
}
this line causing the problem
if(isset($_REQUEST['dataid'])){
$dataid = $_REQUEST['dataid'];
$criteria->addCondition("dataid = $dataid");
}
when, I remove those lines the method work just fine. what could be the problem causing ambigous colum name? here is the error log
SELECT COUNT(DISTINCT "t"."inputdataid") FROM "app_inputdata" "t" LEFT OUTER JOIN "app_ref_periodicdata" "data" ON ("t"."dataid"="data"."dataid") WHERE ((date_input <= :enddate AND date_input >= :startdate) AND (dataid = 7)) AND (data.locationid=:locationid). Bound with :startdate='2013-01-01', :enddate='2015-02-02', :locationid='6'
You need to add the table alias t to your condition:
$criteria->addCondition("t.dataid = $dataid");
Also, since $dataid is being obtained from a $_REQUEST it is best to pass it as a parameter. This can be done in two ways:
$criteria->addCondition("t.dataid = :dataid", [":dataid" => $dataid]);
$criteria->compare("t.dataid", $dataid);
you have used table aliases,
'with'=>array(
'type'=>array(
'condition'=>'type.type_desc=:type_desc', <<- I mean here you have used alias : type
'params'=>array(':type_desc'=>$kategori)
)
you just have to remember that the main model that you are working with, will always need alias t to unambigufy! (not sure if that is an actual word :D )

SQL showing in place of web page

I've copied a codeigniter website from my old computer to my new one, and copied the database. When I navigate to the site in my localhost however, I just get SQL printed out
db->where($cell_name, $id); $this->db->delete($table_name); if (!is_array($tags)) { $tmp = array(); $tmp[] = $tags; $tags = $tmp; } if (!empty($tags)) { foreach($tags as $tag) { switch(gettype($tag)) { case 'integer': $this->db->set($cell_name, $id); $this->db->set('tag_id', $tag); $this->db->insert($table_name); break; case 'string': $tag = strtolower($tag); $results = $this->db->query('SELECT id FROM tag WHERE tag = \''.$tag.'\' LIMIT 1'); if ($results->num_rows() == 1) { $tag_id = $results->first_row()->id; } else { $this->db->set('tag', $tag); $this->db->set('permalink', url_title($tag, 'dash')); $this->db->insert('tag'); $tag_id = $this->db->insert_id(); } $this->db->set($cell_name, $id); $this->db->set('tag_id', $tag_id); $this->db->insert($table_name); break; } } } } function get_active($type, $id, $return_ids = true) { $ret = array(); switch($type) { case 'media': $table_name = 'media_tag'; $cell_name = 'media_id'; break; case 'post': $table_name = 'post_tag'; $cell_name = 'post_id'; break; } if (!$id) { $results = $this->db->query('SELECT tag.id, tag.tag, tag.permalink FROM '.$table_name.', tag WHERE tag_id = tag.id GROUP BY tag.id ORDER BY tag.tag'); if ($results->num_rows() > 0) { foreach($results->result() as $data) { if ($return_ids) $ret[] = $data->id; else $ret[] = (object) array('id' => $data->id, 'tag' => $data->tag, 'permalink' => $data->permalink); } } } else { $results = $this->db->query('SELECT tag.id, tag.tag, tag.permalink FROM '.$table_name.', tag WHERE '.$cell_name.' = '.$id.' AND tag_id = tag.id ORDER BY tag.tag'); if ($results->num_rows() > 0) { foreach($results->result() as $data) { if ($return_ids) $ret[] = $data->id; else $ret[] = (object) array('id' => $data->id, 'tag' => $data->tag, 'permalink' => $data->permalink); } } } return $ret; } }
Does anyone know if there's a simple reason for this - some setting I need to turn on in wamp for example, I'm completely at a loss, the files and database are identical on my old and new computers
It turns out I had simply not allowed "short open tags" from the WAMP PHP settings