How can i forward to other action inside the same controller avoiding repeat all dispatch proccess ?
Example:
If i point to User Controller the default action is indexAction() inside this funciton i use _forwad('list') ... but all dispatch proccess are repeated.. and i dont that
Whats is the right way ?
Usually, you will install routes to redirect your users to the proper (default) action, instead of the index action (read how to redirect from a given route using Zend_Router). But you can do everything manually if you really want to (however this is called "writing hacker code to achieve something dirty") directly from the controller.
Change your "view script" to be rendered, then call your action method....
// inside your controller...
public function indexAction() {
$this->_helper->viewRenderer('foo'); // the name of the action to render instead
$this->fooAction(); // call foo action now
}
If you tend on using this "trick" often, perhaps you may write a base controller that you extend in your application, which can simply have a method like :
abstract class My_Controller_Action extends Zend_Controller_Action {
protected function _doAction($action) {
$method = $action . 'Action';
$this->_helper->viewRenderer($action);
return $this->$method(); // yes, this is valid PHP
}
}
Then call the method from your action...
class Default_Controller extends My_Controller_Action
public function indexAction() {
if ($someCondition) {
return $this->_doAction('foo');
}
// execute normal code here for index action
}
public function fooAction() {
// foo action goes here (you may even call _doAction() again...)
}
}
NOTE : this is not the official way to do it, but it is a solution.
We Can Also use this Helper To redirect
$this->_helper->redirector->gotoSimple($action, $controller, $module, $params);
$this->_helper->redirector->gotoSimple('edit'); // Example 1
$this->_helper->redirector->gotoSimple('edit', null, null, ['id'=>1]); // Example 2 With Params
If you don't want to re-dispatch there is no reason you can't simply call the action - it's just a function.
class Default_Controller extends My_Controller_Action
{
public function indexAction()
{
return $this->realAction();
}
public function realAction()
{
// ...
}
}
You could also create a route. For example I have in my /application/config/routes.ini a section:
; rss
routes.rss.route = rss
routes.rss.defaults.controller = rss
routes.rss.defaults.action = index
routes.rssfeed.route = rss/feed
routes.rssfeed.defaults.controller = rss
routes.rssfeed.defaults.action = index
Now you only need one action and that is index action but the requess rss/feed also goes there.
public function indexAction()
{
...
}
Related
I've tried many solutions that had the same questions like mine. But didn't found a working solution.
I have a controller:
event.php
And two views:
event.phtml
eventList.phtml
I use eventList to get data via ajax call so I want to populate both views with a variable named "eventlist" for example.
Normally I use this code for sending a variable to the view:
$this->view->eventList = $events;
But this variable is only available in event.phtml.
How can I make this available for eventlist.phtml? (without adding a second controller)
Edit:
I get this error now
Call to undefined method Page_Event::render()
Function:
private $_event;
public function init(){
$dbTable = new Custom_Model_DbTable_Events();
//Get Events
$this->_event = $dbTable->getEntries($this->webuser->businessId);
$this->index();
}
public function indexAction(){
$this->eventList = $this->_event;
$this->render();
$this->render('eventlist');
}
If I use $this->view->render('event.phtml') and eventlist.phtml it won't pass the data
I'm using zend version 1
You can pass variables to other views using render()
public function fooAction()
{
// Renders my/foo.phtml
$this->render();
// Renders my/bar.phtml
$this->render('bar');
}
Copy and paste this in your controller and rename your controller from event.php to EventController.php
class EventController extends Zend_Controller_Action
{
private $_event;
public function init(){
$dbTable = new Custom_Model_DbTable_Events();
//Get Events
$this->_event = $dbTable->getEntries($this->webuser->businessId);
$this->index();
}
public function indexAction(){
// You're calling the index.phtml here.
$this->eventList = $this->_event;
$this->render('event');
$this->render('eventlist');
}
}
To specify that only written #Daan
In your action:
$this->view->eventList= $events;
$this->render('eventList'); // for call eventList.phtml
In you View use : $this->eventList
You could render it within the view itself (eventList.phtml), rather than within the controller, using the same line of code you used above:
$this->render('event[.phtml]');
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(){
//[...]
}
}
?>
Hi i have issue here of calling another controller action to send an mail, here is my code:
user.php
public function followAction()
{
$follow_id = $this->_getParam('id');
$response = "<a href='javascript: void(0)' class='i-wrap ig-wrap-user_social i-follow_small-user_social-wrap'><i class='i i-follow_small-user_social ig-user_social'></i>Stop Following</a>";
notifyEmail() ------> need to call Notity Controller with notifyEmail() Action along with
params
$this->_helper->json($response); ----> return json response
}
NotifyController.php
<?php
class NotifyController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function index()
{
}
public function notifyEmailAction()
{
// rest of email code goes here
}
}
Thanks for help!
You have to move send mails functionality to another place,
and call it in both methods.
Check this thread
Calling member function of other controller in zend framework?
I suggest to create at the path /library a new folder 'My' and in it new file Utilities.php and in that file a new class where you can put all your help methods
class My_Utilities {
// put here your custom help methods
}
You need to auto-load that namespace.In configs/application.ini put
autoloaderNamespaces.my = "My_"
Then you can use namespace My_ and class My_Utilities.
In any case, you can call method form another controller:
include 'NotifyController.php';
$a = new NotifyController($this->_request, $this->_response);
$a->notifyEmailAction();
$this->action('action', 'controller', 'module', 'params')
That view helper walk through frontController and dispatch all plugins again.
I think is not the best solution keep in mind wasting resources
Please try this code
$this->action("action","controller","module")
I want to make some action (php script) before all actions in my frontend app and then pass a result from that script to actions in variable - so I can get variable value from all actions. Where should I declare sth like this?
If the filter solution dont feet your needs, you can also create a base action class with a preExecute function:
// app/frontend/lib/baseActions.class.php
class baseActions extends sfActions
{
public function preExecute()
{
$this->myVar = .... // define your vars...
}
}
Then your module actions class extends your baseActions class:
// app/frontend/modules/myModule/actions/actions.class.php
class myModuleActions extends baseActions
{
public function executeIndex(sfWebRequest $request)
{
// var $this->myVar is available in any action and in your template
...
}
}
if you have to use the preExecute function in your module class action, remember to call parent::preExecute() in it.
What kind of information ?
I would recommend you to use filters.
In your apps/frontend/config/filters.yml:
rendering: ~
myfilter:
class: myCustomFilter
Create the file lib/filter/myCustomFilter.php:
<?php
class myCustomFilter extends sfFilter
{
public function execute ($filterChain)
{
if ($this->isFirstCall())
{
// do what ever you want here.
$config = Doctrine_Core::getTable('Config')->findAll();
sfConfig::set('my_config', $config);
}
$filterChain->execute();
}
}
And then, every where, you can retrieve your data:
sfConfig::get('my_config');
I have this thing that I need in multiple places:
public function init()
{
$fbLogin = new Zend_Session_Namespace('fbLogin'); #Get Facebook Session
if(!$fbLogin->user) $this->_redirect('/'); #Logout the user
}
These two lines:
$fbLogin = new Zend_Session_Namespace('fbLogin'); #Get Facebook Session
if(!$fbLogin->user) $this->_redirect('/'); #Logout the user
Whats the best way to do it in ZendFramework?To create a plugin or? I mean I want to execute it in multiple places but If I need to edit it I want to edit it in one place.
Here is an example of an Action Helper that you can call from your controllers easily.
<?php
class My_Helper_CheckFbLogin extends Zend_Controller_Action_Helper_Abstract
{
public function direct(array $params = array())
{
// you could pass in $params as an array and use any of its values if needed
$request = $this->getRequest();
$view = $this->getActionController()->view;
$fbLogin = new Zend_Session_Namespace('fbLogin'); #Get Facebook Session
if(!$fbLogin->user) {
$this->getActionController()
->getHelper('redirector')
->gotoUrl('/'); #Logout the user
}
return true;
}
}
In order to use it, you have to tell the helper broker where it will live. Here is an example code you can put in the bootstrap to do so:
// Make sure the path to My_ is in your path, i.e. in the library folder
Zend_Loader_Autoloader::getInstance()->registerNamespace('My_');
Zend_Controller_Action_HelperBroker::addPrefix('My_Helper');
Then to use it in your controller:
public function preDispatch()
{
$this->_helper->CheckFbLogin(); // redirects if not logged in
}
It doesn't go into much detail, but Writing Your Own Helpers is helpful as well.
If you need this check in every Controller you could even set up a baseController from which you extend instead of the default one:
class My_Base_Controller extends Zend_Controller_Action
{
public function init()
{ ...
class IndexController extends My_Base_Controller
{ ...
Shift your init() into the base controller and you don't need to repeat yourself in every specific controller.
Need a varying init() in a specific controller?
class FooController extends My_Base_Controller
{
public function init()
{
parent::init();
...