Table of Contents
What is resultPageFactory in magento 2 and what is the use of it?
In Magento 2 all controller actions must return something, opposed to M1, where a controller action would just output something or did a redirect.
The result of theΒ execute
Β method from each controller is generated inΒ Magento\Framework\App\FrontController::dispatch()
Β on lineΒ $result = $actionInstance->execute();
Β and returned.
Depending on the type of the returned result a different action is performed.
The result can be and instance of :
\Magento\Framework\View\Result\Page
Β – actually renders html\Magento\Framework\Controller\Result\Redirect
Β – redirects to an other page\Magento\Framework\Controller\Result\Forward
Β – forwards to an other action (internal redirect)\Magento\Framework\Controller\Result\Json
Β – returns a json object.\Magento\Framework\Controller\Result\Raw
Β – returns whatever you tell it to return (string).
What does $this->resultPageFactory->create(); statement means in controller file?
resultPageFactory
Β is an instance ofΒ\Magento\Framework\View\Result\PageFactory
Β and when callingΒcreate
Β on that class it returns an instance ofΒ\Magento\Framework\View\Result\Page
described above.- When this is used and the result is returned it means that your action will return HTML.
It has somehow a similar effect asΒ$this->loadLayout();
from Magento 1. - When you callΒ
create
Β on theΒresultPageFactory
object it actually loads the layout. - When you return a page result object from your execute method, youβre telling Magento to kick off the standard layout handle XML file page rendering.
Magento 2 Controller Result Objects
- Every URL in Magento 2 corresponds to a singleΒ controller file, and each controller file has a singleΒ
execute
Β method. ThisΒexecute
method is responsible for returning a βresultβ object. - Thereβs a number of different objects you can return fromΒ
execute
Β for different sorts of result types.
Page Factories
- You can create a page result by injecting a page factory in your controllerβs constructor.
protected $resultPageFactory; public function __construct( //... \Magento\Framework\View\Result\PageFactory $resultPageFactory //... ) { //... $this->resultPageFactory= $resultPageFactory //... }
and then using the page factory to create your response object inΒ
execute
public function execute() { //... return $this->resultPageFactory->create(); //... }
When you return a page result object from yourΒ
execute
Β method, youβre telling Magento to kick off the standard layout handle XML file page rendering.
Page Results on the Frontend
If you look at a page factoryβs source
#File: vendor/magento/framework/View/Result/PageFactory.php
//...
public function __construct(
ObjectManagerInterface $objectManager,
$instanceName = Magento\Framework\View\Result\Page::class
) {
$this->objectManager = $objectManager;
$this->instanceName = $instanceName;
}
//...
public function create($isView = false, array $arguments = [])
{
/** @var Magento\Framework\View\Result\Page $page */
$page = $this->objectManager->create($this->instanceName, $arguments);
// TODO Temporary solution for compatibility with View object. Will be deleted in MAGETWO-28359
if (!$isView) {
$page->addDefaultHandle();
}
return $page;
}
You see theΒ create
Β method uses the object manager directly to create an object.
$page = $this->objectManager->create($this->instanceName, $arguments);
This objectβs class is set in the constructor, and by default isΒ Magento\Framework\View\Result\Page
.Β However, thanks to this bit of dependency injection
Page Results on the Backend
#File: vendor/magento/module-backend/etc/adminhtml/di.xml
<type name="Magento\Framework\View\Result\PageFactory"><arguments><argument name="instanceName" xsi:type="string">Magento\Backend\Model\View\Result\Page</argument></arguments></type>
the page factory object will return aΒ Magento\Backend\Model\View\Result\Page
Β instead when youβre working in theΒ adminhtml
Β area.
In other words, the above configuration, replaces theΒ $instanceName
parameterβs value in Magento\Framework\View\Result\PageFactory
objects. It replaces it with the string βMagento\Backend\Model\View\Result\Page
β. It only replaces it in the adminhtml area since the file path isΒ etc/adminhtml/di.xml
, which means the configuration is only loaded in theΒ adminhtml
Β area.
So page factory used automatic constructor dependency injection and a di.xml
Β configuration to return the correct type of page object depending on the requestβs location in the frontend (cart) or adminhtml (backend admin) area of the application.
Other Return Types
Letβs see the result types that arenβtΒ page objects. Specifically
- A βJsonβ result
- A βRawβ result
- A βForwardβ result
- A βRedirectβ result
JSON Results
Youβll use a JSON result when you want to return a JSON object. Youβll do this if youβre implementing a custom API endpoint, or a simple AJAX endpoint. If its a JSON result you want, inject the json result factory
public function __construct(
//...
Magento\Framework\Controller\Result\JsonFactory $jsonResultFactory,
//...
)
{
$this->jsonResultFactory = $jsonResultFactory;
}
and then inΒ execute
Β use this factory to create an object, set that new objectβs data, and return the object
public function execute()
{
$result = $this->jsonResultFactory();
$o = new stdClass;
$o->foo = 'bar';
$result->setData($o);
return $result;
}
Raw Result
Youβll use a raw result when you want to return a plain string without Magento layout and view rendering. By default a raw result will be returned with aΒ text/html
Β header, if you want something else (text/xml
,Β text/plain
) then youβll want to use theΒ setHeader
Β method of the result object.
To get a raw result, inject a raw result factory object via automatic constructor dependency injection
public function __construct(
//...
Magento\Framework\Controller\Result $rawResultFactory ,
//...
)
{
$this->rawResultFactory = $rawResultFactory;
}
and use that factory to create a raw result
public function execute(
)
{
//...
$result = $this->rawResultFactory->create();
$result->setHeader('Content-Type', 'text/xml');
$result->setContents('<root><science></science></root>);
return $result;
}
Forwarding Result
Forwarding in Magento 2 is similar to forwarding in Magento 1, and a little tricky if youβve never encountered it before. When you forward a request youβre telling Magentoβs internal system that it should process aΒ differentΒ route without making another HTTP request. I generally stay away from forwarding, because thereβs a lot of unanswered/poorly documented behavior on which controllerβs request (the original or the forwarded) will effect other parts of the system (like layout handles, etc.)
However, forwarding survives in Magento 2 so youβll want to be aware of it.
To use forwarding, inject a forward factory via automatic constructor dependency injection
public function __construct(
//...
Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory
//...
)
{
$this->resultForwardFactory = $resultForwardFactory;
}
and use that factory to create a forward result
public function execute()
{
$result = $this->resultForwardFactory->create();
$result->forward('noroute');
return $result;
}
Redirect Result
When you want to send the user/request to a new URL via an HTTP location header redirect, youβll want a redirect result.
To create a redirect result, inject a redirect factory via automatic constructor dependency injection
public function __construct(
//...
Magento\Framework\Controller\Result\RedirectFactory $resultRedirectFactory
//...
)
{
$this->resultRedirectFactory = $resultRedirectFactory;
}
and then use that factory to create a redirect response
public function execute()
{
$result = $this->resultRedirectFactory->create();
$result->setPath('*/*/index');
return $result;
}
The Role of Factories and Magento Areas
A Magento controller should return a βresultβ object. Each result object does a different thing. Thereβs a result object for pages, internal forwards, redirects, JSON results, and arbitrary/text results. To get different result objects, use their respective factories.