Laravel 4 and debugbar - show pdo queries? - php

I have installed: https://github.com/barryvdh/laravel-debugbar using composer.
I followed install procedures, and now done.
But how do I see my PDO mysql queries? I am building a RESTful api, without any HTML/view rendering.
Don't know if it is for any use, but heres some example of my code:
// the controller
public function feed($exclude = null) {
$feed = $this->item->feed()->with('attributes', 'images', 'user');
if($exclude)
$feed->whereNotIn('id', explode(',', $exclude));
return ['items' => $this->itemTransformer->transformCollection($feed->get()->toArray())]; // woud like to debug this query
}
// the router
Route::get('items/feed/{exclude?}', ['protected' => true, 'uses' => 'ItemsController#feed']);

The Debugbar should log all requests when enabled, even when not outputting HTML. You could try to create 1 simple HTML page so that the Debugbar gets rendered. You can click the Browse button (on the right, next to the close button) to browse previous requests. You should get a list with collected requests, which you can filter by url/ip/method. Clicking that will show that information on the Debugbar.

Easy:
public function feed($exclude = null) {
$feed = $this->item->feed()->with('attributes', 'images', 'user');
if($exclude)
$feed->whereNotIn('id', explode(',', $exclude));
$items = ['items' => $this->itemTransformer->transformCollection($feed->get()->toArray())];
echo json_encode($items); // echo instead of return. Will trigger HTML to render and
}

Related

How can I reload a View after sorting product data in a Laravel controller?

In a site I'm working on, I'm having some problems rendering a view. On the websites products-list page, there's a little 'Sort by...' element. When the user selects one of the options, it should reload the products page with the sorted products, or load the same view on a different URL with the sorted products. Either one is fine, I just want the ordered products to be displayed. Sorting the products in my ProductsController is working out just fine, but I keep running into problems when I want to pass these sorted products to the front-end. The view I'm returning in the code below is the same as the normal view for the products-list page. Just fyi: I'm relatively new to Laravel and used to work mainly with JavaScript, so I might be trying to do this in an exceptionally silly, non-Laravel way.
Ideally, I would just like to pass the sorted products to the Blade file for the products-list page. I've tried that, but I don't know how to trigger a reload. What I then tried, is directing the user to a new route (which I registered in the web.php), where I was planning to render the same Products view, but with sorted data. This didn't work either, and gave me a blank page with a vague jQuery error message.
In the ProductsController.php:
public function sortController($type) {
$available_products = Products::with(['gallery', 'slug'])->get()
->where('status', 'available');
$number_of_products = count($available_products);
$product_names_sorted_by_type
= $this->orderProductTitlesBasedOnNumber($number_of_products, $available_products, $type);
$sorted_products_array = $this->orderProductsBasedOnSortedArray($number_of_products, $available_products, $product_names_sorted_by_type);
$product_brands_controller = new ProductsBrandsController;
$brands_list = $product_brands_controller->getBrandNamesArray();
return view('aanbod')->with([
'title' => 'Ons aanbod',
'products' => $sorted_products_array,
'brands' => $brands_list
]);
}
In my App.js:
function handleSortRequest(sortRequest) {
sortURL = window.location.origin + '/autos/list/sort?q=' + sortRequest
location.href = sortURL
}
In my Web.php:
Route::group(['prefix' => config('site.products.url'), 'as' => 'products.'], function () {
// some other routes...
Route::get('/list/sort/{sort_request}', 'ProductsController#handleSortRequest')->name('sort');
});
Anyway, this isn't working and nothing is rendering at all. I just get a blank page with the following error:
"TypeError: a is undefined - javascript:2771"
This error seems to occur in the jQuery file that the PHPDebugbar uses.
Hope this wasn't to much text. Thanks in advance, let me know how I can improve my Laravel code!
I would instead suggest you to have the sort selection inside a form and upon selecting sort method send a request (via js or by clicking a submit button). Then handle sorting logic in controller based on value of selection and return the view with sorted collection.
Route:
Route::post('/product/list', [
'uses' => 'ProductController#action',
'as' => 'product.action'
]);
ProductController action:
public function action(Request $request)
{
if (isset($request['sort'])) {
// do the sorting logic
}
...
// return view with your sorted products
return view('product.list', ['products' => $sortedProducts]);
}
This is just an example of a more Laravel way of doing it.
If you are doing AJAX request:
ProductController action
...
$view = view('product.list', ['products'=> $sortedProducts])->render();
if ($view) {
return response()->json($view, 200);
} else {
return response()->json(null, 400);
}
...
app.js
// inside ajax request
success: function(data) {
$('#some-container').html(data);
},

CakePHP 3 autocomplete AJAX responses

I have been trying to get cakephp to suggest input from data that is from my tables like autocomplete. I've done some reading about how some other people have done this but still can't figure it out. Currently it seems that every time my controller is waiting for an ajax request and it is always false. No errors come up from the console some i'm not sure what i'm doing wrong. I tried removing the if ($this->request->is('ajax')) statement but then I get a error about it cannot emit headers.
Here is my search function in InvoicesController which I have taken code from someone else example but failed to implement it.
public function search()
{
if ($this->request->is('ajax')) {
$this->autoRender = false;
pr('b');
$name = $this->request->query['term'];
$results = $this->Invoices->find('all', [
'conditions' => [ 'OR' => [
'id LIKE' => $id . '%',
]]
]);
$resultsArr = [];
foreach ($results as $result) {
$resultsArr[] =['label' => $result['full_name'], 'value' => $result['id']];
}
echo json_encode($resultsArr);
}
}
And here is my search.ctp
<?php use Cake\Routing\Router; ?>
<?php echo $this->Form->input('id', ['type' => 'text']);?>
<script>
jQuery('#id').autocomplete({
source:'<?php echo Router::url(array('controller' => 'Invoices', 'action' => 'search')); ?>',
minLength: 1
});
</script>
This is my invoice table and the ids are what I want to be suggested from what users type in.
I may not be seeing your exact problem but let me point out a few things I see that might help this issue.
Remove this line. It is not necessary
$this->autoRender = false;
Instead you should be doing this at the end. See using the RequestHandler
$this->set('resultsArr', $resultsArr);
// This line is what handles converting your array into json
// To get this to work you must load the request handler
$this->set('_serialize', 'resultsArr');
This will return the data without a root key
[
{"label":"Label Value"},
{"label":"Another Label Value"}
]
Or you can do it like this
$this->set('_serialize', ['resultsArr']);
This will return data like
{"resultArr":[
{"label":"Label Value"},
{"label":"Another Value"}
]}
Replace your finder query with this.
$resultArr = $this->Invoices->find('all')
->where(['id LIKE' => $id . '%'])
// If you want to remap your data use map
// All queries are collections
->map(function ($invoice) {
return ['label' => $invoice->full_name, 'id' => $invoice->id];
});
It seems to me you might want to review the new cakephp 3 orm. A lot of hard work went into writing these docs so that they could be easily read and relevant. I'm not one to push docs on people but it will save you hours of frustration.
Cakephp 3 ORM documentation
A few minor things I noticed that are also problems.
You never define $id.
You define $name but never use it.
pr is a debug statement and I am not sure why you have it.
Based on your comment, here is an update on ajax detection.
// By default the ajax detection is limited to the x-request-with header
// I didn't want to have to set that for every ajax request
// So I overrode that with the accepts header.
// Any request where Accept is application/json the system will assume it is an ajax request
$this->request->addDetector('ajax', function ($request) {
$acceptHeaders = explode(',', $request->env('HTTP_ACCEPT'));
return in_array('application/json', $acceptHeaders);
});

How did you bind datas to a view in Codeigniter ( likes View Composers in laravel)?

If you have data that you want to be bound to a view each time that view is
rendered,a view composer can help you ...
This task can be easily archived in laravel, but I am now using Codeigniter, there is no view composers things. What I have done now is, I create a custom view method, just like below
public function view($page,$params=null,$return=false)
{
// Every time I invoke this method, $nav will be passed to 'navigation' view.
$nav=[
'user' =>'Adam'
];
//return the views as view_partials instead of displayed
$view_partials = array(
'navigation' => $this->obj->load->view('partials/nav',$nav,true),
'page_content' => $this->obj->load->view($page,$params,true)
);
// load layout with the view_partials which contain bound data.
$this->obj->load->view($this->_layout,$view_partials,$return);
}
This method returns views as 'string', it can not works with json or complex page.... Thank you.
Ok, lets make this simple
$this->load->view(path_to_htmlpage, $bound_data, FALSE);
or
$this->load->view(path_to_htmlpage, $bound_data); // by default 3rd param is FALSE
this will render html page
If you want to get html page as a string, set 3rd parameter to TRUE
$html_string = $this->load->view(path_to_htmlpage, $bound_data, TRUE);
check https://ellislab.com/codeigniter/user-guide/general/views.html
public function view($page,$params=null,$return=false)
{
$nav['user']='adam';
$data['navigation']= $this->load->view("partials/nav",$nav,true);
$data['page_content'] = $this->load->view($page,$params,true)
$this->load->view('your_page',$data);
}
in yor view page ie.your_page you can use variables $navigation and $page_content to display the pages

Gii model generation not getting past first step - strange bevavior, what's causing this?

I've installed the latest version of yii2 using the advanced template. The website is working fine. For some reason the Gii generation tool is stuck and does not react as expected after clicking the preview button. Instead of showing a new form with the "Generate" button, it shows the same form unchanged without any messages as to what is happening.
Using xdebug I can see in the "actionView" method of the DefaultController that the array value $_POST['preview'] is not set, i.e. it doesn't exist in the $_POST array. I have not changed anything in the Form of the view and everything looks OK. The submit button has the name "preview" and the form is submitted but the $_POST array is not being filled with the value of the submit button. Therefore the controller does not proceed with the next steps of the generation process.
public function actionView($id)
{
$generator = $this->loadGenerator($id);
$params = ['generator' => $generator, 'id' => $id];
// ###############################################################################
// ### THIS IF STATEMENT IS NOT TRUE BECAUSE $_POST['preview'] IS NOT SET !!! ###
// ###############################################################################
if (isset($_POST['preview']) || isset($_POST['generate'])) {
// ###############################################################################
if ($generator->validate()) {
$generator->saveStickyAttributes();
$files = $generator->generate();
if (isset($_POST['generate']) && !empty($_POST['answers'])) {
$params['hasError'] = !$generator->save($files, (array) $_POST['answers'], $results);
$params['results'] = $results;
} else {
$params['files'] = $files;
$params['answers'] = isset($_POST['answers']) ? $_POST['answers'] : null;
}
}
}
return $this->render('view', $params);
}
Does anyone have an idea what could be causing this? I have a hunch that it is something quite simple that I'm overlooking, but I've never had a situation where POST variable from a Form are not being sent to the server.
False Alarm. I've found the problem. The Gii view was creating the HTML Form incorrectly.

cakePHP : combining 2 actions and loading all players and also one player that changes

In my index (/players) view I have a carousel with images of a bunch of players. When I click on an Image I go to the view screen of the clicked player (/players/view/1).
Now I want to only have an index screen with that carousel of player images and after I click on an Image I want the information of that player on that same index screen.
How would I best combine the index and view so that I can click on a player image and retrieve his information on the same page? The goal is to have one view file and one action in the controller. So how can I put find('all') and find('first') in one action?
Now I have /players and /players/view/1.
I want to have for instance /players/1 so it loads on the same page. However this will still give a page load I think.
Eventually I don't want a page load, but only a content change.
index action of PlayersController (gives me all the players) :
public function index() {
$this->layout = 'default_front_players';
$this->Player->recursive = 0;
//$this->Player->find('all');
$this->set('players', $this->Paginator->paginate());
}
view action of PlayersController (gives me the player that has been clicked) :
public function view($id = null) {
$this->layout = 'default_front_players';
if (!$this->Player->exists($id)) {
throw new NotFoundException(__('Invalid player'));
}
$options = array('conditions' => array('Player.' . $this->Player->primaryKey => $id));
$this->set('player', $this->Player->find('first', $options));
}
UPDATE
First case
This gives me all the players and gives me also one player (atm player 143, the last one in the database), problem is that when I click on a players image the player stays on player 143. The url changes to players/index/{number of clicked player}
public function index($id = null) {
$this->layout = 'default_front_players';
$this->Player->recursive = 0;
$players = $this->Player->find('all');
$this->set(compact('players'));
$options = array('conditions' => array('Player.' . $this->Player->primaryKey => $id));
$player = $this->set('player', $this->Player->find('first', $options));
}
Second case
This doesn't shows me the player images, but when I change the url, it gives me the content of the player which id I give in the URL.
public function index($id = null) {
$this->layout = 'default_front_players';
$this->Player->recursive = 0;
//$players = $this->Player->find('all');
//$this->Paginator->settings = $this->paginator_players;
$this->set('players');
$options = array('conditions' => array('Player.' . $this->Player->primaryKey => $id));
$player = $this->set('player', $this->Player->find('first', $options));
}
If I go to /players or players/index I don't get any values.
How can I combine these 2?
Have you tried ajax and routes to achieve a content refresh ( essentially creating your own api call to internal resources )? I use cakephp for my own side project, and needed a way to circumvent the whole controller, view load mechanism for a faster UI experience.
The gist is including jquery in your template or layout file. When a certain route or url is called ( this requires a route to be setup in your routes.php file in app/config relatively from your apps root folder ) , fire the ajax call to fetch the content and dynamically update the dom without having to reload the page.
This suggestion might open up a whole new can of worms for you, but its achievable I think.

Categories