How to change layout in my all action of zend framework2 - php

In my project where i have two modules, one is the frontend and the other is the backend,Because there are two different layout on the screen so each,Now I can change lauout on a single Action,I want to emulate zf1, the controller there is a init () method, you can perform, so that all action to change lauout or have any way to work.
zf1 init() Method
class AjaxController extends Zend_Controller_Action
{
function init(){
$this->_helper->layout()->disableLayout();
}
}
zf2 __construct() Method
public function __construct()
{
$this->layout('layout/administrator');//it's not work
}
pulic funciton indexAction()
{
$this->layout('layout/administrator');//it's work
}

Read this post: Module-specific layouts in Zend Framework 2

ZF1 and ZF2 are very different in terms of their architecture. ZF2 is event driven; meaning that you will need to attach an event listener to the controller dispatch event or order for it to correctly set the layout.
class Module
{
public function getControllerConfig()
{
return array(
'factories' => array(
'Namespace\Controller\Ajax' => function($cpm) {
$controller = new Namespace\Controller\Ajax();
$eventManager = $controller->getEventManager();
$eventManager->attach('dispatch', function($event) {
// Set layout or perform actions prior to dispatch
$controller = $event->getTarget(); // Controller
$controller->layout('foo/bar');
});
return $controller;
},
),
);
}

Related

How can I call commoly used functions in slim 3 framework?

I am building my website in Slim 3 MVC framework.I need to call some commonly used functions for controller (Eg: For Alias of page title I am using a function called function getAlias(){.....}).
Where I have to create those functions? How can I call inside controllers?
There's a number of ways to do this. If the functions have no side effects, then one option would be to have a utilities class with static methods in it it.
Another option would be to extend all your route actions from a common class and use that:
// CommonAction.php
class CommonAction
{
protected function getAlias() { }
}
// HomeAction.php
class HomeAction extends CommonAction
{
public function __construct(/*dependencies here*/) { }
public function __invoke($request, $response, $args) {
// route action code here
return $response;
}
}
// index.php
$app = new Slim\App(require('settings.php'));
$container = $app->getContainer();
$container[HomeAction::class] = function ($c) {
return new HomeAction(/*dependencies*/);
}
$app->get('/', HomeAction::class);
$app->run();
If the functionality is part of your domain layer, then inject those classes into your route actions as a dependency.

Zend 1 plugin before set routing

I need get plugin before load routes. I use routeStartup and preDispatch in plugin, but it doesn't help.
class Base_Controller_Plugin_Website extends Zend_Controller_Plugin_Abstract
{
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
Base_Website::setRequest($request);
}
}
I need method from Base_Website.
The earliest front-controller plugin event is routeStartup, so if you want to perform some action prior to that, you'll need to do it in Bootstrap.
Unfortunately, the methods that run during bootstrap don't pass the Request and Response objects to you. You'll have to dig them out yourself. Something like:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
// all your other _initXXX() bootstrap methods
// etc...
protected function _initSomethingUsingRequest()
{
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$request = $front->getRequest();
// Now do whatever you want with your Request object
// etc...
}
}

ZF2 - pass variables to zend build-in helper

I would like to pass variable (that would be service menager) to a build-in helper of zend. Is it possible? To be more clearly:
There is a zend helper called Url, which constructs url's
In this helper I would like to get some data from database, so I need to pass there connection or model (doesn't matter really)
Depends on data get in point 2. I would like to construct my custom link
Well, the thing looks like this: I'm trying to make own custom routing. So in database I have controller, action and it's alias. For example:
Home\Controller\Home | index | myalias
Routing works fine, that means that if I type url:
example.com/myalias
Then Zend will open Home controller and index action. But on whole page I have url's made by Zend build-in Url helper, which looks like this:
$this->url('home', array('action' => 'index'));
So link looks:
example.com/home/index
I would like to change link to
example.com/myalias
without changing links generated by Url helper on whole page. So before helper return url, should check if that url have alias, and if so then should return that alias exept regular url.
In Module.php of the module where you have he helper class file, write the following -
//use statements
class Module {
//public function getAutoloaderConfig() { [...] }
//public function getConfig() { [...] }
public function getViewHelperConfig() {
return array(
'factories' => array(
'Url' => function ($sm) {
$locator = $sm->getServiceLocator();
$viewHelper = new View\Helper\Url;
//passing ServiceLocator to Url.php
$viewHelper->setServiceLocator($locator); //service locator is passed.
return $viewHelper;
},
),
);
}
}
Now in the Url.php, we need a function setServiceLocator() and getServiceLocator().
//use statements
class Url {
public $serviceLocator;
public function getServiceLocator() {
return $this->serviceLocator;
}
public function setServiceLocator($serviceLocator) {
if($this->serviceLocator == null)
$this->serviceLocator = $serviceLocator;
return;
}
}
I hope it helps.

Php Yii, How to register for a event raised by a controller

What I want to do: Register a component to an event raised by a controller.
In my config main.php:
'preload' => array(MessageConsumer) // actually an impl class of interface
In my MessageConsumer impl
public function init() {
Yii::app()->getController()->onMessageReceived = array($this, 'onMessageReceived');
}
Expected result: when the init method fires the consumer is registered to the current controller.
Actual result: there's no current controller yet. It seems the pre-load is performed before the webapplication does the controller magic.
So I tried something like:
In my MessageConsumer impl:
public function init() {
$self = $this;
Yii::app()->onBeginRequest(function() use ($self) {
$controller = Yii::app()->getController();
if($controller instanceof MessagingController) {
Yii::app()->getController()->onMessageReceived = array($self, 'onMessageReceived');
}
});
}
Which doesn't work either because it seems the init() is called after the onBeginRequest() event is raised by the webapp.
Is there a way to register to events raised by a controller without explicitly linking the component to the controller class? Obviously I could register the listener in the constructor of the controller but I want to loosely couple the 2 components by using configuration.
Maybe there's some event like "onComponentLoaded" for which I could register? Since a Controller is a component I'd expect the Yii core to fire the event whenever there's a component loaded if there's such an event at all.
I presume this is what you looking for, the onBeforeAction();
<?php
class YourController extends Controller
{
//this action is executed before any controller action
protected function beforeAction($action)
{
//do stuff before controll action
return true;
}
//the rest ofyour controller actions and stuff
public function actionIndex(){
//[...]
}
}
?>

How do I centralize code from my init functions in all controllers?

public function init(){
$this->view->user = Zend_Auth::getInstance()->getIdentity();
$this->view->siteName = Zend_Registry::get('config')->site->name;
$this->view->menu = $this->_helper->generateMenu(Zend_Auth::getInstance()->getIdentity());
$this->view->slogan = Zend_Registry::get('config')->site->slogan;
}
This is the init file in all of my controllers across all modules, is there a place I can put this code so it executes every request irregardless of the module/controller being called?
I'd rather advise you to write a plugin by extending Zend_Controller_Plugin_Abstract, it is its purpose.
By this way, you will have no need to do anything anywhere in your controller.
Then you can use the registry to access to your data...
class My_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
protected $_auth = null;
protected $_acl = null;
public function __construct (Zend_Auth $auth, Zend_Acl $acl)
{
$this->_auth = $auth;
$this->_acl = $acl;
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
//some code
}
}
And then in your bootstrap.php
$this->_front->registerPlugin(new My_Controller_Plugin_Layout());
http://framework.zend.com/manual/en/zend.controller.plugins.html
To share code across controllers, create an Action Helper which was designed primarily to solve the problem you have.
They can be run "on demand":
$myHelper = $this->_helper->MyHelper;
$myHelper->someFunction();
and also have a set of hooks that the dispatch process will call automatically. To use the hooks, you need to register the action helper with the broker:
$helper = new App_Controller_Action_Helper();
Zend_Controller_Action_HelperBroker::addHelper($helper);
The available hooks are:
init()
preDispatch()
postDispatch()
For more info,the manual page can be found at http://framework.zend.com/manual/en/zend.controller.actionhelpers.html and I have written a couple of articles about them: http://akrabat.com/2008/10/31/using-action-helpers-in-zend-framework/ and http://akrabat.com/2008/11/05/hooks-in-action-helpers/
You can extend Zend_Controller_Action:
public class My_Controller_Action extends Zend_Controller_Action
{
public function init()
{
$this->view->user = Zend_Auth::getInstance()->getIdentity();
$this->view->siteName = Zend_Registry::get('config')->site->name;
$this->view->menu = $this->_helper->generateMenu(Zend_Auth::getInstance()->getIdentity());
$this->view->slogan = Zend_Registry::get('config')->site->slogan;
}
}
Then you just change your controllers to extend My_Controller_Action rather than Zend_Controller_Action. Just keep in mind that if you need to add additional code to the init method of a controller, you'll have to invoke parent::init() as well:
public class FooController extends My_Controller_Action
{
public function init()
{
parent::init();
// Do something.
}
public function IndexAction()
{
// ...
}
}

Categories