Symfony2, check if an action is called by ajax or not - ajax

I need, for each action in my controller, check if these actions are called by an ajax request or not.
If yes, nothing append, if no, i need to redirect to the home page.
I have just find if($this->getRequest()->isXmlHttpRequest()), but i need to add this verification on each action..
Do you know a better way ?

It's very easy!
Just add $request variable to your method as use. (For each controller)
<?php
namespace YOUR\Bundle\Namespace
use Symfony\Component\HttpFoundation\Request;
class SliderController extends Controller
{
public function someAction(Request $request)
{
if($request->isXmlHttpRequest()) {
// Do something...
} else {
return $this->redirect($this->generateUrl('your_route'));
}
}
}
If you want to do that automatically, you have to define a kernel request listener.

For a reusable technique, I use the following from the base template
{# app/Resources/views/layout.html.twig #}
{% extends app.request.xmlHttpRequest
? '::ajax-layout.html.twig'
: '::full-layout.html.twig' %}
So all your templates extending layout.html.twig can automatically be stripped of all your standard markup when originated from Ajax.
Source

First of all, note that getRequest() is deprecated, so get the request through an argument in your action methods.
If you dont want to polute your controller class with the additional code, a solution is to write an event listener which is a service.
You can define it like this:
services:
acme.request.listener:
class: Acme\Bundle\NewBundle\EventListener\RequestListener
arguments: [#request_stack]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onRequestAction }
Then in the RequestListener class, make a onRequestAction() method and inject request stack through the constrcutor. Inside onRequestAction(), you can get controller name like this:
$this->requestStack->getCurrentRequest()->get('_controller');
It will return the controller name and action (I think they are separated by :). Parse the string and check if it is the right controller. And if it is, also check it is XmlHttpRequest like this:
$this->requestStack->getCurrentRequest()->isXmlHttpRequest();
If it is not, you can redirect/forward.
Also note, that this will be checked upon every single request. If you check those things directly in one of your controllers, you will have a more light-weight solution.

Related

exclude blocks in twig during ajax requests [duplicate]

I need, for each action in my controller, check if these actions are called by an ajax request or not.
If yes, nothing append, if no, i need to redirect to the home page.
I have just find if($this->getRequest()->isXmlHttpRequest()), but i need to add this verification on each action..
Do you know a better way ?
It's very easy!
Just add $request variable to your method as use. (For each controller)
<?php
namespace YOUR\Bundle\Namespace
use Symfony\Component\HttpFoundation\Request;
class SliderController extends Controller
{
public function someAction(Request $request)
{
if($request->isXmlHttpRequest()) {
// Do something...
} else {
return $this->redirect($this->generateUrl('your_route'));
}
}
}
If you want to do that automatically, you have to define a kernel request listener.
For a reusable technique, I use the following from the base template
{# app/Resources/views/layout.html.twig #}
{% extends app.request.xmlHttpRequest
? '::ajax-layout.html.twig'
: '::full-layout.html.twig' %}
So all your templates extending layout.html.twig can automatically be stripped of all your standard markup when originated from Ajax.
Source
First of all, note that getRequest() is deprecated, so get the request through an argument in your action methods.
If you dont want to polute your controller class with the additional code, a solution is to write an event listener which is a service.
You can define it like this:
services:
acme.request.listener:
class: Acme\Bundle\NewBundle\EventListener\RequestListener
arguments: [#request_stack]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onRequestAction }
Then in the RequestListener class, make a onRequestAction() method and inject request stack through the constrcutor. Inside onRequestAction(), you can get controller name like this:
$this->requestStack->getCurrentRequest()->get('_controller');
It will return the controller name and action (I think they are separated by :). Parse the string and check if it is the right controller. And if it is, also check it is XmlHttpRequest like this:
$this->requestStack->getCurrentRequest()->isXmlHttpRequest();
If it is not, you can redirect/forward.
Also note, that this will be checked upon every single request. If you check those things directly in one of your controllers, you will have a more light-weight solution.

How to Call a controller function in another Controller in Laravel 5

im using laravel 5.
I need to call a controller function but this should be done in another controller.
I dont know how to do this
public function examplefunction(){
//stuff
}
And i have a Route for this function, so at
public function otherfunctioninothercontroller(){
// I need examplefunction here
}
how Can i do this?
1) First way
use App\Http\Controllers\OtherController;
class TestController extends Controller
{
public function index()
{
//Calling a method that is from the OtherController
$result = (new OtherController)->method();
}
}
2) Second way
app('App\Http\Controllers\OtherController')->method();
Both way you can get another controller function.
If they are not in the same folder, place use namespace\to\ExampleClass; on top of your file, then you are able to instantiate your controller.
You can simply instantiate the controller and call the desired method as follows
FirstController.php:
namespace App\Http\Controllers;
class FirstController extends Controller {
public function examplefunction() {
// TODO: implement functionality
}
}
SecondController.php:
namespace App\Http\Controllers;
class SecondController extends Controller {
public function test() {
$object = new FirstController();
$object->examplefunction();
}
}
Now, after i've answered the question, i would like to add the following comment:
Controllers are classes, all rules that applies to normal classes can be applied to them
However, instantiating a controller directly inside another controller to call a desired method signifies a problem in your design for the following 2 reasons:
A controller cannot obtain an instance of another controller directly
Controller should contain as little business logic as possible, and if possible none
The closest possible solution to what you want (WITHOUT BREAKING MVC) is to make an HTTP request to the route that points to the desired method (using cURL, for example) and read the response as the returned data
But this still doesn't make much sense in this scenario because after all you're making an HTTP request from a method in a controller in your project on your server to a method in a controller in your project on your server, seems like unnecessary overhead, right ?
As i said earlier, a controller should contain as little business logic as possible because the logic should stay inside specialized classes (commonly known as Service Classes), and when a processing is requested the controller simply delegates the job of processing to the appropriate service class which does the processing and returns the results to the controller which in turn sends it back as a response
Now imagine if you've the following scenario:
We've got an application that consists of 3 functionalities:
A user can register an account from web application
There's a mobile application that talks to an API to register a user
There's an admin panel, which he can use to add new user
Obviously you need to create 3 controllers, but those controllers contains repeated logic, would you copy/paste the code everywhere ?
Why not encapsulate this logic inside a service class and call it from the controller when needed ?
Let's say I have Controller1 and Controller2. I want to call a function of Controller1 from inside a function placed in Controller2.
// Controller1.php
class Controller1 {
public static function f1()
{
}
}
And on the other controller:
// Controller2.php
use App\Http\Controllers\Controller1;
class Controller2 {
public function f2()
{
return Controller1::f1();
}
}
Points to be noted:
f1() is declared static
A call to a controller from inside another controller is a bad idea. There is no sense of meaning of controllers then. You should just redirect to web.php to save safe whole architecture like this:
class MyController {
public function aSwitchCaseFunction(Request $requestPrm){
...
//getting path string from request here
...
switch($myCase){
case CASE_1:
return redirect()->route('/a/route/path');
....
}
}
}

Pass data from routes.php to a controller in Laravel

I am attempting to create a route in Laravel for a dynamic URL to load a particular controller action. I am able to get it to route to a controller using the following code:
Route::get('/something.html', array('uses' => 'MyController#getView'));
What I am having trouble figuring out is how I can pass a variable from this route to the controller. In this case I would like to pass along an id value to the controller action.
Is this possible in Laravel? Is there another way to do this?
You are not giving us enough information, so you need to ask yourself two basic questions: where this information coming from? Can you have access to this information inside your controller without passing it via the routes.php file?
If you are about to produce this information somehow in your ´routes.php´ file:
$information = WhateverService::getInformation();
You cannot pass it here to your controller, because your controller is not really being fired in this file, this is just a list of available routes, wich may or may not be hit at some point. When a route is hit, Laravel will fire the route via another internal service.
But you probably will be able to use the very same line of code in your controller:
class MyController extends BaseController {
function getView()
{
$information = WhateverService::getInformation();
return View::make('myview')->with(compact('information'));
}
}
In MVC, Controllers are meant to receive HTTP requests and produce information via Models (or services or repositores) to pass to your Views, which can produce new web pages.
If this information is something you have in your page and you want to sneak it to your something.html route, use a POST method instead of GET:
Route::post('/something.html', array('uses' => 'MyController#getView'));
And inside your controller receive that information via:
class MyController extends BaseController {
function getView()
{
$information = Input::get('information');
return View::make('myview')->with(compact('information'));
}
}

Call an index controller with parameter

So basically, I have a setup of restful controller in my route. Now my problem is how can I call the Index page if there is a parameter.. it gives me an error of Controller not found
Im trying to call it like this www.domain.com/sign-up/asdasdasd
Route::controller('sign-up','UserRegisterController');
then in my Controller
class UserRegisterController extends \BaseController {
protected $layout = 'layouts.unregistered';
public function getIndex( $unique_code = null )
{
$title = 'Register';
$this->layout->content = View::make( 'pages.unregistred.sign-up', compact('title', 'affiliate_ash'));
}
By registering:
Route::controller('sign-up','UserRegisterController');
You're telling the routes that every time the url starts with /sign-up/ it should look for corresponding action in UserRegisterController in verbAction convention.
Suppose you have:
http://domain.com/sign-up/social-signup
Logically it'll be mapped to UserRegister#getSocialSignup (GET verb because it is a GET request). And if there is nothing after /sign-up/ it'll look for getIndex() by default.
Now, consider your example:
http://domain.com/sign-up/asdasdasd
By the same logic, it'll try looking for UserRegister#getAsdasdasd which most likely you don't have. The problem here is there is no way of telling Route that asdasdasd is actually a parameter. At least, not with a single Route definition.
You'll have to define another route, perhaps after your Route::controller
Route::controller('sign-up','UserRegisterController');
// If above fail to find correct controller method, check the next line.
Route::get('sign-up/{param}', 'UserRegisterController#getIndex');
You need to define the parameter in the route Route::controller('sign-up/{unique_code?}','UserRegisterController');. The question mark makes it optional.
Full documentation here: http://laravel.com/docs/routing#route-parameters

Should I call redirect() from within my Controller or Model in an MVC framework?

I'm using the MVC PHP framework Codeigniter and I have a straight forward question about where to call redirect() from: Controller or Model?
Scenario:
A user navigates to www.example.com/item/555. In my Model I search the item database for an item with the ID of 555. If I find the item, I'll return the result to my controller. However, if an item is not found, I want to redirect the user somewhere. Should this call to redirect() come from inside the model or the controller? Why?
No your model should return false and you should check in your controller like so:
class SampleModel extends Model
{
//Construct
public function FetchItem($id)
{
$result = $this->db->select("*")->from("table")->where("item_id",$id)->get();
if($result->num_rows() == 0)
{
return false;
}
//return result
}
}
and within your controller do:
function item($id)
{
$Item = $this->SampleModel->FetchItem($id);
if(!$Item)
{
redirect("class/error/no_item");
}
}
Models are for data only either return a standard result such as an key/value object or a boolean.
all logic should be handled / controlled by the Controller.
Models are not page specific, and are used globally throughout the whole application, so if another class / method uses the model, it might get redirect to the incorrect location as its a different part of your site.
It seems like the controller would be the best place to invoke your redirect because the controller typically delegates calls to the model, view, or in your case, another controller.
However, you should use whatever makes the most sense for your application and for what will be easier to maintain in the future, but also consider that rules do exist for a reason.
In short, if a coworker were to try to fix a bug in your code, what would the "reasonable person" standard say? Where would most of them be most likely to look for your redirect?
Plus, you said you're returning the result to your controller already... perhaps that's where you should make your redirect...

Resources