I create a action helper file path is
C:\xampp\htdocs\ecom\application\controllers\helpers
file name :Inputdata.php
class Zend_Controller_Action_Helper_Inputdata extends Zend_Controller_Action_Helper_Abstract
{
function Inputdata()
{
return $this;
}
function fetch_db_value($var)
{
if(get_magic_quotes_gpc()==0) {
return is_array($var) ? array_map(array($this,'fetch_db_value'), $var) : nl2br(stripslashes(trim($var)));
}else {
return is_array($var) ? array_map(array($this,'fetch_db_value'), $var) : nl2br(trim($var));
}
}
}
I am calling this function on controller giving output proper like :
$dbData=$this->_helper->Inputdata->fetch_db_value($dbData);
I have also a view helper, path is
C:\xampp\htdocs\ecom\application\views\helpers
file name : Comman.php
class Zend_View_Helper_Comman
{
public function displayProducts($res){
# Res is a array
foreach($res as $val){
# $val also is sub array of array $res
$val=$this->_helper->Inputdata->fetch_db_value($val);
print_r($val)
}
}
}
this function
$this->_helper->Inputdata->fetch_db_value
is giving error
any idea about syntax how to user action helper custom function in view helper custom function
syntax how call function displayProducts() on controller
Re: the action helper:
The namespace prefix on your action helper is Zend_. The autoloader will look for it in the location in which the Zend Framework library resides. In order for the autoloader - the resource loader, in this case - to look for the action helper in application/controllers/helpers, the namespace prefix has to be the appnamespace, typically Application_. So renaming the class to Application_Controller_Helper_Inputdata should do the trick.
Re: the view helper:
A similar thing applies. Typically, you would use the appnamespace prefix Application_. So renaming the class to Application_View_Helper_Comman should make the displayProducts() method accessible in a view-script as:
$this->comman()->displayProducts($res)
You mention referencing the view-helper method in a controller. This is typically not done; view-helpers are usually referenced only in view-scripts. However, if you really want to do it, you can access it via the View object. In a controller:
$this->_view->comman()->displayProducts($res)
If that view-helper is only going to contain that single displayProducts() method, then you can rename that class to be Application_View_Helper_DisplayProducts and reference the method in a view-script using:
$this->displayProducts($res)
Related
I'm working on small PHP framework (for learning). It has a file with LoginController class containing a method with Route attribute (code below). Is there any way to get the name of the method in the Route attribute class using Reflection?
Class with method using attribute:
class LoginController {
#[Route('GET', '/login')]
public function index() {
// some code
}
}
"Route" attribute class:
use Attribute;
use ReflectionMethod;
#[Attribute]
class Route {
public function __construct($method, $routeUri) {
// Can I get the method name ("index") from attribute instead of writing it?
// And the class name?
$reflection = new ReflectionMethod(\App\Controllers\LoginController::class, 'index');
$closure = $reflection->getClosure();
// Register a route...
Router::add($method, $routeUri, $closure);
}
}
Reflection is an option, but please be aware that you will be looping over all the attributes of all the methods in a class (at least until a matching one is found). Of course, if all routes need to be registered, this isn't that bad.
$classRef = new ReflectionClass(LoginController::class);
foreach ($classRef->getMethods() as $method) {
$methodRef = new ReflectionMethod($method->class, $method->name);
foreach ($methodRef->getAttributes() as $attribute) {
if (
$attribute->getName() === 'Route'
&& $attribute->getArguments() === [$method, $routeUri]
) {
// you can register your route here
}
}
}
As far as classes go, the easiest way to go is just make an array with all your controller class names. There are packages out there that can detect all classes in a given namespace, which could be used for autodetecting your controllers.
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()
So, lets say I have a global view and specific view.
In global view, the url may look like this (http://example.com/index.php/controller/method/)
Where when it come to the specific page view, the url will turn like this:
(http://example.com/index.php/controller/method/1989-03-25)
The difference between the global view and the specific page view is, if in the global view it shows the information in general, but in the specific page view it shows based on the detail or the date.
Of course, not only have different view, but also they will have different function of models.
The point is, I just want to make the url keep in order (which it mean there is no change in the name of the controller method).
How to do this. Thanks in advance.
You create just one param into your function. And set the param value is null. like this
class YOUR_CLASS extends CI_controller {
public function method($params=null) //null is Empty value
{
if($params)
{
//load your modal and view with your param
}
else
{
//load your modal and view
}
}
}
This method supports the following type of URL's without any issue.
http://example.com/index.php/YOUR_CLASS/method/
http://example.com/index.php/YOUR_CLASS/method/1989-03-25
Hope this will help you....
This class used to wrap CI_controller, my_base_controller will override CI_controller methods for depends to your project needs
class my_base_controller extends CI_controller {
}
You can load models by known states and define it in my_base_controller class.
class my_controller extends my_base_controller{
public function method($params=null) //null is option value
{
}
}
Good luck!
You can add additional parameter in your method like:
class Your_controller extends CI_controller {
public function method($params = null)
{
// Your Code Here with the condition for processing of the $params variable
}
}
in which that $params can be something in your URL like:
http://example.com/controller/method/your-dynamic-params
So if the $params is null you will call the model the views the general and if the $params has a specific value you can call other model by using if or switch conditional statements. Hope this helps...
Update with Example
you can use the $params variable like this:
if ($params == "1991") {
$this->load->view('general.html', $params);
} elseif ($params == "1992") {
$this->load->view('year_1992.html', $params);
} else {
$this->load->view('other_years.html', $params)
}
in this way you can use the $params as a conditional variable to load different views.
or using switch:
switch($params) {
case '1991':
$this->load->view('general.html', $params);
break;
case '1992':
$this->load->view('year_1992.html', $params);
break;
default:
$this->load->view('other_years.html', $params)
}
Note: Use a helper method so you can avoid fat controllers because it will be hard to test your methods if you have a several lines of codes in a function.
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")
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()
{
...
}