Where orWhere Laravel 5.5 logical DB issue - database

I am in agony
This is my helper
$friend_query = Friend::where([
'user_id' => Auth::id(),
'friend_id' => $friend_id,
])->orWhere([
'user_id' => $friend_id,
'friend_id' => Auth::id(),
])->first();
$friendship = new stdClass();
$friendship->exist = false;
$friendship->accepted = false;
if (! is_null($friend_query))
{
$friendship->accepted = $friend_query->accepted;
$friendship->exist = true;
}
var_dump($friendship->exist);
exit;
return $friendship;
And when I am logged as 'user_id' => auth::id() - everything is fine but when I am logged as 'friend_id' who got request always var_dump return me true... This is third day I can not find solution. The photo of DB included in post.

When you want to "group" your where clauses, you should pass a closure instead then perform your condition inside it. Say for example, you want your query to look like this
SELECT * FROM friends WHERE (user_id = ? AND friend_id = ?) OR (user_id = ? AND friend_id = ?) LIMIT 1
Then the eloquent version of this would be
$friend_query = Friend::where(function ($query) use ($friend_id) {
$query->where('user_id', Auth::id())
->where('friend_id', $friend_id);
})->orWhere(function ($query) use ($friend_id) {
$query->where('friend_id', Auth::id())
->where('user_id', $friend_id);
})->first();

Thank you,
just little syntax error should be
->orWhere(function ($query) {
but there is one problem - Undefined variable: friend_id
it goes like this
function friendship($friend_id){
friend_query = Friend::where([
'user_id' => Auth::id(),
'friend_id' => $friend_id,
])->orWhere(function ($query) {
$query->where([
'user_id' => $friend_id,
'friend_id' => Auth::id(),
]);
})
->first();
... }

Try it like this :
$friend_query = Friend::where([
'user_id' => Auth::id(),
'friend_id' => $friend_id,
])
->orWhere(function ($query) use($friend_id) {
$query->where([
'user_id' => $friend_id,
'friend_id' => Auth::id(),
]);
})
->first();

Related

How to access data from a query to a CGridView

I'm trying to use on my view a search made by CreateCommand to fill my CGridView, but I still need to pass as a dataProvider a CActiveDataProvider object.
Is there any way to transform my CreateCommand object into CActiveDataProvider or to do the same query directly as a CActiveDataProvider?
This is the view
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'credenciado-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'afterAjaxUpdate' => "loadAfterAjax",
'rowHtmlOptionsExpression' => 'array("style"=>"cursor: pointer","data-row-id" => $data->cre_id, "class" => "row_grid")',
'columns' => array(
'cre_razao_social',
array(
'header'=>'Status',
'name'=>'cre_ativo',
'value'=>'Status::getStatus($data->cre_ativo)',
'filter'=>array(true => 'ATIVO',false => 'INATIVO'),
'filterHtmlOptions'=>array('class'=>'col-sm-2'),
),
),
)); ?>
This is the controller
$model = new Credenciado('getValoresCredenciadosByConvenioRank');
$model = new CArrayDataProvider($model, array());
// pe($model);
$modelEst = new Estabelecimento('search_adm');
// pe($model);
$modelEst->unsetAttributes();
if (isset($_GET['Estabelecimento']))
$modelEst->setAttributes($_GET['Estabelecimento']);
// $model->unsetAttributes();
// if (isset($_GET['Credenciado']))
// $model->setAttributes($_GET['Credenciado']);
$this->render('listar',array(
'model' => $model,
'modelEst' => $modelEst,
'mes1' => $mes1,
'mes2' => $mes2,
'meses' => $meses,
'produto' => $produto,
'data' => $format,
'datas' => $date_unique,
'series' => $series,
'ano1' => $ano1,
'ano2' => $ano2
));
}
This is the Model
$q = Yii::app()->db->createCommand()
->select("
cre.cre_razao_social,
count(op.ope_id) as linhas,
par.par_data_vencimento,
pro.pro_codigo,
SUM(
CASE
WHEN date_trunc('month',par_data_vencimento) < date_trunc('month',now()) AND pro_codigo != 2 THEN
par.par_valor
WHEN pro_codigo = 2 THEN
op.ope_valor_parcela
ELSE
op.ope_valor_parcela
END
) as total_carteira")
->from("operacao op")
->join('parcela par', 'par.par_operacao_ope_id = op.ope_id')
->join('pos po', 'po.pos_id = op.ope_pos_pos_id')
->join('rubrica_credenciado rub', 'rub.rub_id = po.pos_rubrica_credenciado_rub_id')
->join('credenciado cre','rub.rub_credenciado_cre_id = cre_id')
->join('produto pro', 'pro.pro_id = rub.rub_produto_pro_id')
->join('matricula ma', 'ma.mat_matricula = op.ope_matricula AND ma.mat_convenio_con_id = '.Yii::app()->user->convenioid.' ')
->where('op.ope_con_id = :con_id', array(':con_id' => $con_id));
$q->andWhere(
"(par.par_data_vencimento between :datamin and :datamax and ope_status in('E','S'))
OR
(par.par_data_vencimento between :datamin and :datamax AND par.par_num_parcela = op.ope_qtde_parcelas AND op.ope_status = 'Q')
",
array(':datamin'=>$datamin, ':datamax'=>$datamax));
if(Yii::app()->user->sistema != 1) {
$q->andWhere('rub_consignavel = true');
}
$q->order('par.par_data_vencimento', 'ASC');
//$q->andWhere(array('in', 'ope_status', array('E','S')));
$q->group('cre.cre_razao_social, pro.pro_codigo, par.par_data_vencimento');
$q->queryAll();
This is the error
exception 'CException' with message 'CArrayDataProvider and its behaviors
do not have a method or closure named "search".' in
/var/www/html/yii/framework/base/CComponent.php:266
Stack trace:
you are making a mistake in your view. In your controller you are already passing object of CArrayDataProvider (i.e $model) to your view, so you should not call search() function on $model variable. Instead you should create CArrayDataProvider object from CreateCommand in your model and pass the object of Credenciado as $model in your controller and call your query method in the view like $model-> getValoresCredenciadosByConvenioRank() to get the data provider. Then your view would look like this
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'credenciado-grid',
// call your query function to get data provider (this is the name of function that you have implemented in your model)
'dataProvider' => $model->getValoresCredenciadosByConvenioRank(),
'filter' => $model,
'afterAjaxUpdate' => "loadAfterAjax",
'rowHtmlOptionsExpression' => 'array("style"=>"cursor: pointer","data-row-id" => $data->cre_id, "class" => "row_grid")',
'columns' => array(
'cre_razao_social',
array(
'header'=>'Status',
'name'=>'cre_ativo',
'value'=>'Status::getStatus($data["cre_ativo"])',
'filter'=>array(true => 'ATIVO',false => 'INATIVO'),
'filterHtmlOptions'=>array('class'=>'col-sm-2'),
),
),
));
?>
Your controller would become this
$model = new Credenciado('getValoresCredenciadosByConvenioRank');
$model->unsetAttributes();
if (isset($_GET['Credenciado']))
$model->setAttributes($_GET['Credenciado']);
// pe($model);
$modelEst = new Estabelecimento('search_adm');
// pe($model);
$modelEst->unsetAttributes();
if (isset($_GET['Estabelecimento']))
$modelEst->setAttributes($_GET['Estabelecimento']);
$this->render('listar',array(
'model' => $model,
'modelEst' => $modelEst,
'mes1' => $mes1,
'mes2' => $mes2,
'meses' => $meses,
'produto' => $produto,
'data' => $format,
'datas' => $date_unique,
'series' => $series,
'ano1' => $ano1,
'ano2' => $ano2
));
}
And your model would return CArrayDataProvider instead of query result like this,
$queryResult = $q->queryAll();
// return data provider for view instead of query result
return new CArrayDataProvider($queryResult, array());
Hopefully this solution will solve your problem. Let me know if it works or if the problem still persists.

Retrive data using cakephp

I am new to cakephp and i want to find data that has been created
This is my sql function works
Select Trv_No from Ticket_LO
This is my model in cakephp
$ticket = $this->Ticket->find('first', array('conditions' => array('AND' => array('Ticket.TRV_No' => $trv_no)));
if(empty($ticket))
{
$table_name = 'Ticket_L0';
$this->Ticket->setSource($table_name);
//$ticket = $this->Ticket->find('first', array('conditions' => array('Ticket.TRV_No' => $trv_no)));
$ticket = $this->Ticket->find('first', array('conditions' => array('AND' => array('Ticket.TRV_No' => $trv_no, 'Ticket.HIDDEN_STAT LIKE' =>'0'))));
if(empty($ticket)) { return false; } else { return true; }
}
else
{ return true; }
}
First things first,
You don't need to set $this->Ticket->setSource($table_name); in your model.
You can use $this->find
I'm not sure what do you really want. But, I guess you want something like that.
$ticket = $this->find('first', array(
'conditions' => array(
'Ticket.TRV_No' => $trv_no,
'Ticket.HIDDEN_STAT'=> 0 //if you want to find 0 only, you don't need LIKE. But, if you want some string, you can use something like 'Ticket.HIDDEN_STAT LIKE'=>'yourString%'
)
)
);
And, you can add your condition after that.
if(!empty($ticket)) return true;
else return false;

Array to DB::insert()->values(), which is in different order with the columns

Hi folks! I'm trying to transfer data as array from the controller to the model, and then paste the data into the query builder, but the data must be in the same order as specified in the columns.
What options do I have?
And do you think this is a bad practice?
Controller:
$responseNotes = Model::factory('Notes')-> createTicket([
'description' => htmlspecialchars($_POST['description']),
'contact_id' => $_POST['contact_id'],
'pref_contact' => $_POST['pref_contact'],
'dog_id' => $_POST['document_id'],
'type' => $_POST['type'],
'owner_id' => Auth::instance()->get_user()->id,
'cc' => $_POST['cc-emails'],
'title' => $_POST['title']
]);
Model:
public function createNote(array $data)
{
$columns = [
'type',
'owner_id',
'cc',
'title',
'description',
'contact_id',
'pref_contact',
'dog_id'
];
if (!array_diff($columns, array_keys($data))) {
// All needed values exists
$result = DB::insert($this->NOTES, $columns)-> values($data)-> execute($this->SCHEMA);
}
return ($result) ? $result : false ;
}
Thanks to this answer. Solved this by:
// Order $data array according to $column.values
$orderedData = [];
foreach ($columns as $key) {
$orderedData[$key] = $data[$key];
}
$result = DB::insert($this->TICKETS, $columns)
-> values($orderedData)
-> execute($this->SCHEMA);
Why you don't use ORM Model?
in controller:
$responseNotes = ORM::factory('Notes')-> values([
'description' => htmlspecialchars($_POST['description']),
'contact_id' => $_POST['contact_id'],
'pref_contact' => $_POST['pref_contact'],
'dog_id' => $_POST['document_id'],
'type' => $_POST['type'],
'owner_id' => Auth::instance()->get_user()->id,
'cc' => $_POST['cc-emails'],
'title' => $_POST['title']
])
try{
$responseNotes->save();
} catch (ORM_Validation_Exception $ex) {
print_r($ex->errors('models'));
}
And don't use htmlspecialchars($_POST['description'])
In model class modify function (doc):
public function filters()
{
return array(
'description' => array( array('htmlspecialchars') ),
);
}
It looks like You have associative array with structure db_column=>value right? Than You can simply insert like this:
DB::Insert('table_name',array_keys($data))->values(array_values($data))->execute();

Update field in a Column on Laravel

I'm trying to update the status on my tickets table to the value : 2.
Once I can create the comment... (is working.. :) ), I wanted to change the status to 2.
This is my ticket model and the following function:
public function addComment($id,$body,$solved)
{
$this->find($id)->status = 2;
$this->save();
$this->comments()->create([
'ticket_id' => $id,
'body' => $body,
'user_id' => auth()->id()
]);
}
You need to get your object first then you can Update it:
public function addComment($id,$body,$solved)
{
$ticket = $this->find($id);
$ticket->status = 2;
$ticket->save();
$ticket->comments()->create([
'ticket_id' => $id,
'body' => $body,
'user_id' => auth()->id()
]);
}
Try changing your code like this. Maybe this will fix the problem you're having:
public function addComment($id,$body,$solved)
{
$ticket = Ticket::find($id);
$ticket->status = 2;
$ticket->save();
$ticket->comments()->create([
'ticket_id' => $id,
'body' => $body,
'user_id' => auth()->id()
]);
}

Cakephp 3 search query, with concat

I'm trying to perform a search on two joined columns, fname and lname.
This does not appear to be working:
Object of class Cake\Database\Expression\FunctionExpression could not be converted to string
$users = $this->Users->find();
$users->select(['id', 'fname', 'lname'])
->where([$users->func()->concat(['fname', 'lname']).' LIKE' => $terms]);
Any ideas?
Thanks.
If you're concatenating first and last names, they should be concatenated with spaces in between.
$users->select(['id', 'fname', 'lname'])
->where(function ($exp, $query) use ($terms) {
$conc = $query->func()->concat([
'fname' => 'identifier', ' ',
'lname' => 'identifier'
]);
return $exp->like($conc, $terms);
});
Yu have to use query expression but this can't be done in a pagination array.
So Following ndn suggestion here's how I would do
create a custom finder. In your UsersTable file
public function findByKeyword(Query $query, array $options)
{
$keyword = $options['keyword'];
$query->where(
function ($exp, $q) use($keyword){
$conc = $q->func()->concat([
'Users.fname' => 'literal', รน
'Users.lname' => 'literal']);
return $exp
->or_([
'Users.fname LIKE' => "%$keyword%",
'Users.lname LIKE' => "%$keyword%",
])
->like($conc, "%$keyword%");
}
);
return $query;
}
Controller
$this->paginate = [
'finder' => [
'byKeyword' => [
'keyword' => $this->request->data['Users']['keyword']
]],
'conditions' => $limo, // this will merge your $limo conditions
// with the ones you set in the custom finder
'order'= > ['Users.fname desc'],
];
$this->set('userlist', $this->paginate($this->Users));
I think you have to use SQL expressions. Try something like this:
->where(function ($exp, $q) use($terms) {
$concat = $q->func()->concat([
'fname' => 'identifier',
'lname' => 'identifier'
]);
return $exp->like($concat, $terms);
});

Resources