Add items to query result - Laravel - json

I'm slowly moving my API to Laravel and coming to grips with the Query Builder.
I'm trying to achieve this:
$data = array();
$query = "SELECT * FROM blog_posts WHERE post_type = 3 AND post_status = 1 ORDER BY id DESC";
$result = mysqli_query($cms_connection, $query);
if($result) {
while($row = mysqli_fetch_assoc($result)) {
$row['post_seo'] = seoUrl($row['post_title']);
$data['data'][] = $row;
}
$data['success'] = true;
$response = json_encode($data);
}
My problem isn't necessarily with getting the query, but as you can see I'm using the result of the query and then injecting it back into the final array.
So essentially, I'm fetching rows, transforming some of the attributes fetched, and then injecting the newly created attributes into the resulting array.
This is what I have so far:
$posts = DB::table('blog_posts')
-where(['post_type' => 1, 'post_status' => 1)
->orderBy('id', 'desc')
->take(5)->get();

You could do it this way
// get your data (yours part of code)
$posts = DB::table('blog_posts')
-where(['post_type' => 1, 'post_status' => 1])
->orderBy('id', 'desc')
->take(5)->get();
// add post_seo
foreach ($posts as $post) {
$post->post_seo = seoUrl($post->post_title);
}
// set result array
$data['data'] = $posts;
$data['success'] = true;
// response
$response = response()->json($data);
// or in case you want to return it just
return response()->json($data);
EDIT
You could do it also a bit better, using Eloquent. If you have such model (you need to add valid namespaces and use statements)
class BlogModel extends Model
{
protected $table = 'blog_posts';
protected $appends = ['post_seo'];
public function getPostSeoAttribute($value)
{
return seoUrl($this->post_title);
}
}
(added accessor to post_seo attribute and added post_seo to results when converting to array)
You can now do (shorter syntax than in previous example):
// get your data
$posts = BlogPost::where('post_type',1)
->where('post_status',1)
->orderBy('id', 'desc')
->take(5)->get();
// response
$response = response()->json(['data' => $posts, 'success' => true]);

Related

Using AJAX returned JSON encoded data in Codeigniter

I am relatively new to codeigniter. While I was trying to perform a searching operation on my data base using AJAX, The code is returned as successful and the data is retrieved but, This data is JSON encoded and is in the javascript portion of my view so I am unable to use the json_decode function of codeigniter
public function lookup(){
$keyword = $this->input->post('term');
$data['response'] = 'false'; //Set default response
$query = $this->MAutocomplete->lookup($keyword); //Search DB
if( ! empty($query) )
{
$data['response'] = 'true'; //Set response
$data['message'] = array(); //Create array
foreach( $query as $row )
{
$data['message'][] = array(
'id'=>$row->id,
'value' => $row->firstname,
); //Add a row to array
}
}
echo json_encode($data); //echo json string
}
the data is accessed in the javascript as data.message.
Please tell me is there anyway i can use this data in the php part of my program
<?php
class MAutocomplete extends CI_Model{
function lookup($keyword){
$this->load->database();
$this->db->select('*');
$this->db->from('Students');
$this->db->like('firstName',$keyword,'after');
$query = $this->db->get();
// echo '<pre>'; print_r($query->result()); exit;
return $query->result();
}
}
I think you need to parse json response in Ajax's success function using JSON.parse().Like this..
$.ajax({
url:'',//your url
dataType:'JSON',
data:'',//your data
success:function(response){
data = JSON.parse(response);
alert(data.message.value);//alerts value
}
});
In controller use count rather than empty.To check the array
if( count($query) >0 )
{
$data['response'] = 'true'; //Set response
$data['message'] = array(); //Create array
foreach( $query as $row )
{
$data['message'][] = array(
'id'=>$row->id,
'value' => $row->firstname,
); //Add a row to array
}
}
You should use to response:
return $this->output
->set_content_type('application/json')
->set_output(json_encode($data));

JSON response return HTML inside a Loop

I have this function in Laravel 5.1
public function calcolaKilometri()
{
$partenza = Input::get('partenza');
$destinazione = Input::get('destinazione');
$distanceMatrix = new DistanceMatrix(new Client(), new GuzzleMessageFactory());
$response = $distanceMatrix->process(new DistanceMatrixRequest(
[$partenza],
[$destinazione]
));
foreach ($response->getRows() as $row) {
foreach ($row->getElements() as $element) {
$distance = $element->getDistance();
$text = $distance->text;
$value = $distance->value;
$data = ['text' => $text, 'value' => $value];
return \Response::json($data);
}
}
}
need to return to Ajax JSON data but this function return plain HTML response, because we are in a forech loop. How i can do the trick?
I'm not sure I fully understand what you're saying but I assume you want to return all of the data found when looping through your result set in a single JSON response.
Try something like this:
// Your previous code...
// Initialise a $data array here, that we're going to fill with data
$data = [];
foreach ($response->getRows() as $row) {
foreach ($row->getElements() as $element) {
$distance = $element->getDistance();
$text = $distance->text;
$value = $distance->value;
// Append the new set of data to your array
$data[] = ['text' => $text, 'value' => $value];
}
}
// Return the data as JSON only when we've filled it with everything
return response()->json($data);
Try This...
$json = json_encode($data);
return \Response::json($json);
Solved using sessions. If someone have the same issue:
public function calcolaKilometri()
{
$partenza = Input::get('partenza');
$destinazione = Input::get('destinazione');
$distanceMatrix = new DistanceMatrix(new Client(), new GuzzleMessageFactory());
$response = $distanceMatrix->process(new DistanceMatrixRequest(
[$partenza],
[$destinazione]
));
foreach ($response->getRows() as $row) {
foreach ($row->getElements() as $element) {
$text = $element->getDistance()->getText();
$value = $element->getDistance()->getValue();
\Session::put('testo', $text);
\Session::put('valore', $value);
}
}
// Return the data as JSON only when we've filled it with everything
$testo = \Session::get('testo');
$valore = \Session::get('valore');
$result = ['text' => $testo, 'value' => $valore];
return \Response::json($result);
}

How do I use a custom query in the model yii2 framework

How do I use a custom query in a model using the yii2 framework? I am trying but errors occurs.
I am a beginner in Yii2 Framework.
Here is my login model:
public function getUser($id)
{
$return = User::findBySQL("Select * from User where userType = 'AHP' and userid = '$id';");
return($return['AHPName']);
}
findOne()
Returns a single active record model instance by a primary key or an
array of column values.
$data = User::findOne(['userType' => 'AHP', 'userid' => $id]);
This will find the user whose user type is AHP and whose userid is $id.
public function getUser($id)
{
$data = User::findOne(['userType' => 'AHP', 'userid' => $id]);
return $data['AHPName'];
}
Try with ActiveQuery:
public function getUser($id)
{
$data = User::find()->where(['userType' => 'AHP', 'userid' => $id])->one();
return $data['AHPName'];
}
using custom queries:
public function getUser($id)
{
$sql = "Select * from User where userType = 'AHP' and userid = '.$id.'";
$return = User::findBySQL($sql)->one();
return $return->AHPName;
}
you can try this technique for writing a custom query in yii2
<?php
use yii\db\Query;
$query = new Query();
$query->select(['*'])->from('user')
->where('user.userType=:id',['id'=>'AHP'])
->andWhere('user.userid=:no',['no'=>$id]);
$command = $query->createCommand();
$result = $command->queryAll();
?>
another to do this
User::find()->where('userType = :type and userid = :id',
['type'=>AHP, 'id' => $id])->one();

JOIN works in SQL not in Drupal

I'm trying to make a module for Drupal 7.x. At a certain point I want to use a sql query (JOIN). When I try the query in MYSQL it works. But when I want to try it in Drupal, the array is empty.
So I guess there is a difference between the sql query and the drupal query (mayby the implemantion is different).
SQL Query
SELECT * FROM friends
INNER JOIN users
ON friends.uid=users.uid
Drupal implementation
function project_myfriends(){
// Use database API to retrieve tasks
$query = db_select('friends', 'f');
$query->join('users', 'u', 'f.uid = u.uid'); // JOIN
$query->fields('u', array('name'))
->execute();
return $query;
}
/**
* Implements hook_block_view().
*/
function project_block_view($delta = ''){
switch ($delta) {
case 'project':
$block['subject'] = t('My Friends');
// Use our custom function to retrieve data
$result = project_myfriends();
$items = array();
var_dump($result);
foreach($result as $friend){
$items[] = array(
'data' => $friend->name,
);
}
// No tasks
if (empty($items)) {
$block['content'] = t('No friends.');
}
else {
// Pass data trough theme function
$block['content'] = theme('item_list', array(
'items' => $items));
}
}
return $block;
}
Thx in advance
You forgot to fetch your result query:
$result = project_myfriends()->execute()->fetchAll();
var_dump($result);

Laravel 4 Method Improvement

I have this index method:
public function index()
{
// In the view, there are several multiselect boxes (account managers, company names and account types). This code retrives the values from the POST method of the form/session.
$company_names_value = Input::get('company_names_value');
$account_managers_value = Input::get('account_managers_value');
$account_types_value = Input::get('account_types_value');
// If there has been no form submission, check if the values are empty and if they are assign a default.
// Essentially, all of the records in the table column required.
if (is_null($company_names_value))
{
$company_names_value = DB::table('accounts')
->orderBy('company_name')
->lists('company_name');
}
if (is_null($account_managers_value))
{
$account_managers_value = DB::table('users')
->orderBy(DB::raw('CONCAT(first_name," ",last_name)'))
->select(DB::raw('CONCAT(first_name," ",last_name) as amname'))
->lists('amname');
}
if (is_null($account_types_value))
{
$account_types_value = DB::table('account_types')
->orderBy('type')
->lists('type');
}
// In the view, there is a dropdown box, that allows the user to select the amount of records to show per page. Retrieve that value or set a default.
$perPage = Input::get('perPage', 10);
// This code retrieves the order from the session that has been selected by the user by clicking on a table column title. The value is placed in the session via the getOrder() method and is used later in the Eloquent query and joins.
$order = Session::get('account.order', 'company_name.asc');
$order = explode('.', $order);
// Here we perform the joins required and order the records, then select everything from accounts and select their id's as aid. Then whereIn is used to select records where company name, account manager name and account type matches the values of the multiselect boxes or the default set above.
$accounts_query = Account::leftJoin('users', 'users.id', '=', 'accounts.user_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->orderBy($order[0], $order[1])
->select(array('accounts.*', DB::raw('accounts.id as aid')));
if (!empty($company_names_value)) $accounts_query = $accounts_query->whereIn('accounts.company_name', $company_names_value);
$accounts = $accounts_query->whereIn(DB::raw('CONCAT(users.first_name," ",users.last_name)'), $account_managers_value)
->whereIn('account_types.type', $account_types_value)
->paginate($perPage)->appends(array('company_names_value' => Input::get('company_names_value'), 'account_managers_value' => Input::get('account_managers_value'), 'account_types_value' => Input::get('account_types_value')));
$accounts_trash = Account::onlyTrashed()
->leftJoin('users', 'users.id', '=', 'accounts.user_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->orderBy($order[0], $order[1])
->select(array('accounts.*', DB::raw('accounts.id as aid')))
->get();
$message = Session::get('message');
$default = ($perPage === null ? 10 : $perPage);
$this->layout->content = View::make('admin.accounts.index', array(
'accounts' => $accounts,
'accounts_trash' => $accounts_trash,
'company_names' => DB::table('accounts')->orderBy('company_name')->lists('company_name', 'company_name'),
'account_managers' => DB::table('users')->orderBy(DB::raw('CONCAT(first_name," ",last_name)'))->select(DB::raw('CONCAT(first_name," ",last_name) as amname'))->lists('amname', 'amname'),
'account_types' => DB::table('account_types')->orderBy('type')->lists('type', 'type'),
'perPage' => $perPage,
'message' => $message,
'default' => $default
));
}
Basically, I am building a query that searches several tables (hence the joins). In the view a user has the ability to select multiple values from various multi-select boxes and then submit a form which will then populate the $company_names_value, $account_managers_value and $account_types_value variables.
Initially, when there is no form submission, I'm using Query Builder to select all records for each type, and then using them in the query.
It works but it is slow and messy. I was wondering if any of you Laravel 4 gurus could help me improve it further, so that the queries are faster and the code is lighter.
Thanks in advance.
This has now been refactored significantly, and it is very fast now. I've moved most of my code in to my models, as well as refactoring that code.
Here's the new index method:
public function index()
{
$account = explode(',', Input::get('account'));
$account_manager = explode(',', Input::get('account_manager'));
$account_type = explode(',', Input::get('account_type'));
$perPage = Input::get('perPage', 10);
$order = Session::get('account.order', 'company_name.asc');
$order = explode('.', $order);
$accounts = Account::accounts($order, $account, $account_manager, $account_type)->paginate($perPage)->appends(array(
'account' => Input::get('account'),
'account_manager' => Input::get('account_manager'),
'account_type' => Input::get('account_type'),
'perPage' => Input::get('perPage')
));
$accounts_trash = Account::accountsTrash($order)->get();
$message = Session::get('message');
$default = ($perPage === null ? 10 : $perPage);
$this->layout->content = View::make('admin.accounts.index', compact('accounts', 'accounts_trash', 'message', 'default'));
}
And the new getAccountByName() method in my controller that is used during my AJAX call. This should probably go in the model:
public function getAccountByName()
{
$name = Input::get('account');
return Account::select(array('id', DB::raw('company_name as text')))->where('company_name', 'like', "%$name%")->get();
}
And finally two new methods in my model for retrieving accounts and accounts trash:
public function scopeAccounts($query, $order, $account, $account_manager, $account_type)
{
$query->leftJoin('users', 'users.id', '=', 'accounts.user_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->orderBy($order[0], $order[1])
->select(array('accounts.*', DB::raw('accounts.id as aid')));
if (!empty($account[0])) {
$query = $query->whereIn('accounts.id', $account);
}
if (!empty($account_manager[0])) {
$query = $query->whereIn('users.id', $account_manager);
}
if (!empty($account_type[0])) {
$query = $query->whereIn('account_types.id', $account_type);
}
}
public function scopeAccountsTrash($query, $order)
{
$query->onlyTrashed()
->leftJoin('users', 'users.id', '=', 'accounts.user_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->orderBy($order[0], $order[1])
->select(array('accounts.*', DB::raw('accounts.id as aid')));
}
Again, there's probably a ton of things to get tidied up here but I'm certainly closer to a much faster and cleaner solution. Doing it like this has reduced the loading times from 12 seconds to 234ms.