Zend Framework calling another Controller Action - php

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")

Related

Yii1: Controller::beforeRender in Yii2

I'm migrating an old app developed in Yii1 to Yii2.
I used to have a array in the controller that was storing all the variables that I would need to send to the frontend as a JavaScript:
public $jsVars;
public function toJSObject($params){
$this->jsVars = array_merge($this->jsVars, $params);
}
private function printJSVarsObject(){
//convert my php array into a js json object
}
When I needed a variable to be exposed in Javascript, I would just use $this->toJSObject, in the View or in the Controller.
Then, in the controller I also used to have:
public function beforeRender($view){
$this->printJSVarsObject();
}
In Yii2, I had to configure the View component with a custom View and then attach an event:
namespace app\classes;
use yii\base\Event;
use yii\helpers\Json;
Event::on(\yii\web\View::className(), \yii\web\View::EVENT_END_BODY, function($event) {
$event->sender->registerJSVars();
});
class View extends \yii\web\View {
public $jsVars = [];
public function addJsParam($param){
$this->jsVars = array_merge($this->jsVars, $param);
}
public function registerJSVars() {
$this->registerJs(
"var AppOptions= " . Json::htmlEncode($this->jsVars) . ";",
View::POS_END,
'acn_options'
);
}
}
But, having the event outside the class seems weird to me. Also, while I'm in the controller, I won't be able to use my former approach using this method.
Obviously, I'm missing something, or my approach is just incorrect.
How do you guys do that?
If you're trying to access properties of the controller from a view (see above comments!), you can use;
$this->context
to return an instance of the currently used controller from within the view file. So to access your beforeRender() method you would just use
$this->context->beforeRender()

Zend passing data to other view

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]');

Cakephp call an component method inside a helper

I use Cakephp 2.1 and I need to call a component method which resides in a plugin, from a view helper:
The component is here:
/app/Plugin/Abc/Controller/Component/AbcComponent.php
The helper is here:
/app/View/Helper/SimpleHelper.php
I tried inside helper:
App::import('Component', 'Abc.Abc');
$this->Abc = new Abc(); or $this->Abc = new AbcComponent;
or
$this->Abc = $this->Components->load('Abc.Abc');
inside the controllers this component works with no problem.
I know this isn't recommended (MVC design etc.) but if I don't use it this way I need to duplicate a lot of code. I need to make something like:
MyHelper extends Helper{
$simpleVar = Component->get_data();
}
I use CakePHP 2.4
This is how I successfully call Component from a Helper:
App::uses('AclComponent', 'Controller/Component');
class MyHelper extends AppHelper {
public function myFunction() {
$collection = new ComponentCollection();
$acl = new AclComponent($collection);
// From here you can use AclComponent in $acl
if ($acl->check($aro, $aco) {
// ...
}
}
}
Passing data from CakePHP component to a helper
This seems to be a very nice way to handle this.
I tried working the way you are before, and, although it seems to be a nice immediate solution, in the long run, it is better to just work with the component and helper as 2 separate entities in your controller.
lee
You can put logic in trait and use this from component and helper, if your porpouse is to use the same business logic in different places, to avoid duplication code.
By example
the trait (file app/Lib/NameOfTrait.php or app/PluginName/Lib/NameOfTrait.php)
trait NameOfTrait {
public function theTraitFunc($a, $b) {
// Code here
}
}
The Component:
App::uses('Component', 'Controller');
App::uses('NameOfTrait', 'PluginName.Lib');
class NameOfComponent extends Component {
use NameOfTrait;
private $member;
private $controller;
public function __construct(ComponentCollection $collection, $settings = array()) {
parent::__construct($collection, $settings);
$this->member = $settings['memberName'];
}
function startup(Controller $controller) {
$this->controller = $controller;
}
/**
* Wrap function call of trait function,
* I think the function doesn't have the same name,
* I don't try this but I think is obvious,
* to avoid the function to call itself
*/
public function theTraitFuncWrap($a) {
return $this->theTraitFunc($a, $this->member);
}
}
Do The same for the Helper.
I hope this help someone, bye :)

Zend Framework how to do this in order to not repeat myself

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();
...

Zend Framework _forward to other action inside same controller

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()
{
...
}

Categories