Zend: Get the current url for use in Controller - php

I have this controller which will simply change the language in a session so I can set it in the bootstrap.
Except I want to change '$this->_redirect ( 'library/recipes/list' );' to be the URL of the page they are on. Ive tried a few functions and they dont seem to work.
Im a newbie Zend user, thanks!
class Library_LanguageswitchController extends Zend_Controller_Action {
public function init() {
$this->_helper->layout->disableLayout ();
$this->_helper->viewRenderer->setNoRender ();
}
public function switchAction() {
$session = new Zend_Session_Namespace ( 'whatcould' );
$session->language = $this->_getParam ( 'lang' );
$this->_redirect ( 'library/recipes/list' );
}
}

There is no built-in way to do this afaik. You want to redirect back to the referer, which may or may not be stored in $_SERVER['HTTP_REFERER'].
The best approach I can think of is writing a Zend_Controller_Action_Helper with a method signature like this
// Returns the referer from $_SERVER array or $fallback if referer is empty
public function getReferer($fallback);
// proxy to getReferer()
public function direct($fallback);
Then you could use
public function switchLanguageAction
{
// ... insert code to switch the language for this user ...
$this->_redirect( $this->_helper->referer('/fallback/to/url') );
}
As an alternative, you could use a custom redirect helper that can achieve the same in one go.

http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelper.redirector.basicusage mentions $this->_redirector->redirectAndExit();

I think that maybe you are looking at this from the wrong angle. A controller is fired after the routing has completed. From what I am seeing you really want to change the language and then route to the controller. This would be achieved via customizing the front controller and tapping in to one of the events there.

Another simple way to grab/set the referer is via adding a param to your frontController in your Bootstrap code:
$frontController = Zend_Controller_Front::getInstance();
$frontController->setParam('referer', $_SERVER['HTTP_REFERER']);
and then grab the referer from your controller like so:
$referer = $this->getInvokeArg('referer');
From the Zend docs for Zend_Controller_Front:
7.3.4. Front Controller Parameters
In the introduction, we indicated that the front controller also acts as a registry for the various controller components. It does so through a family of "param" methods. These methods allow you to register arbitrary data – objects and variables – with the front controller to be retrieved at any time in the dispatch chain. These values are passed on to the router, dispatcher, and action controllers.

Zend not have function for this. But simple way, save url in session and use it here

You can use something like:
$current_page_url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

Related

How to achieve this kind of url routing in codeigniter

i want to achieve url routing something like www.example.com/alicia
suppose alicia is not a class name or method name just something like passing data in url and with some class i want to access this and want to use it for further process.How i can use it ? Thanks in advance.
You can use Codeigniter's built-in routing, the file route.php is located in your config folder.
there you can add:
$route['alicia'] = 'welcome/index/something';
$route['alicia/:any'] = 'welcome/index/someotherthing/$1';
then in your controller, for example welcome you just create a function like:
public function index($page = null){
if($page=='something'){
// do what you need to do, for example load a view:
$this->load->view('allaboutalicia');
}
elseif ($page=='someotherthing'){
// here you can read in data from url (www.example.com/alicia/2017
$year=$this->uri->segment(2); // you need to load the helper url previously
}else{
// do some other stuff
}
}
documentation on routing and on urlhelper
edit after comment:
in case your uri segment is representing a variable, like a username, then you should use a uri scheme like www.example.com/user/alice and create your route like:
$route['user/:any'] = 'welcome/index/user';
then in your controller welcome
public function index($page=null){
if($page=='user'){
// do what you need to do with that user
$user=$this->uri->segment(2); // you need to load the helper url
}
else{
// exception
}
}
This could be tricky because you don't want to break any existing urls that already work.
If you are using Apache, you can set up a mod_rewrite rule that takes care to exclude each of your controllers that is NOT some name.
Alternatively, you could create a remap method in your base controller.
class Welcome extends CI_Controller
{
public function _remap($method)
{
echo "request for $method being handled by " . __METHOD__;
}
}
You could write logic in that method to examine the requested $method or perhaps look at $_SERVER["REQUEST_URI"] to decide what you want to do. This can be a bit tricky to sort out but is probably a good way to get started.
Another possibility, if you can think of some way to distinguish these urls from your other urls, would be to use the routing functionality of codeigniter and define a pattern matching rule in the routes.php file that points these names to some controller which handles them.
I believe that the default_controller will be a factor in this. Any controller/method situations that actually correspond to a controller::method class should be handled by that controller::method. Any that do not match will, I believe, be assigned to your default_controller:
$route['default_controller'] = 'welcome';

How to call a function of a controller from a view?

There is a controller :
use Phalcon\Mvc\Controller;
class ReferentielClientController extends Controller
{
public function indexAction(){
// moteur de template pour une View
$this->view->act_form = 'ReferentielClient/ajouterClient';
return $this->view->pick("client/listerClient");
}
public function ajouterClientAction(){
$this->view->action_form = 'ajouterClientExec';
return $this->view->pick("client/ajouterClient");
}
...
}
From a view I want to call the indexAction method of the controller ReferentielClientController. How to do that ?
Short answer: You can't.
You can't since indexAction is not a normal method, it's an action. Actions aren't called by anyone in the usual way that methods are, they are called with routes an url. Let me explain this a little bit further:
Using MVC, we have the following route using :
http://www.example.org/a/b/c
a is which we call module.
b is which we call controller.
And c is which we call action.
Index actions and default modules will not appear in the URL.
So, how to call functions from view? Better not to. Best way to proceed is to do everything in your controller and pass that info to the view. I.e.:
public function indexAction(){
$this->view->myInfo = $allMyInformationInOneObject;
}
And then, in the view (index.phtml):
<p>
<?php echo $this->myInfo ?>
</p>
Summary:
You don't need to call any controller function from the view, just give it that info from the controller.
Added info about redirection
OK, answering to your commentary. What you want is not to call that function but to redirect the browser to that action.
So, I'll suppose you have your route created in your router, if not, please, go to the Zend documentation about routing. It's highly recommended to create routes instead of using the URL itself.
I guess that you will not be able to use the normal redirecting using href on a button or such, so you will need to use the redirector helper. Since you are not in a controller, you are not able to use the helper by using:
$this->_helper->redirector->gotoUrl($url);
So you will need to instance the redirector like this:
$redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
$redirector->gotoUrl($url);
Being this $url, the URL given by your router, as you can read in the link above.
This can be done but I strongly recommend not to redirect from the view but from the controller. It would be good that all the logic remains in the controller.
I hope this helps!
Ok I found it : I set the href to point to the controller : Annuler

_remap or URI Routing in codeigniter

I am currently looking into the PHP Framework Codeigniter and understand the main concepts so far until the Controllers section about _remapping. I have a understanding how _remapping overwrites the behaviour of controller methods over the URI eg from www.example.com/about_me to www.example.com/about-me. What i would like to hear is peoples opinions on what to use- _remapping method or the URI Routing method? Im only asking this as when researching these methods and someone has been troubled on remapping functions, they have been directed to use URI Routing.
So..
1) What is the main common method to use and the pro's over the other one?
2) Is it best to use URI Routing for PHP5 CI version 2 onwards?
I would be grateful to hear your opinions!
Assuming you do not want to use the index (i.e. http://www.yourdomain.com/category) action of your Categories controller, you can use routes.
$route['category/(:any)'] = 'category/view/$1';
Then you simply need a View action within your Category controller to receive the Category name, i.e. PHP.
http://www.yourdomain.com/category/PHP
function View($Tag)
{
var_dump($Tag);
}
Should you still want to access your index action within your controller, you can still access it via http://www.yourdomain.com/category/index
You should use _remap if you want to change the behaviour of default CI's routing.
For example, if you set a maintenance and want to block any specific controller from running, you can use a _remap() function loading your view, and which will NOT call any other method.
Another example is when you have multiple methods in your URI. Example:
site.com/category/PHP
site.com/category/Javascript
site.com/category/ActionScript
Your controller is category but methods are unlimited.
There you can use a _remap method as called by Colin Williams here:
http://codeigniter.com/forums/viewthread/135187/
function _remap($method)
{
$param_offset = 2;
// Default to index
if ( ! method_exists($this, $method))
{
// We need one more param
$param_offset = 1;
$method = 'index';
}
// Since all we get is $method, load up everything else in the URI
$params = array_slice($this->uri->rsegment_array(), $param_offset);
// Call the determined method with all params
call_user_func_array(array($this, $method), $params);
}
To sum up, if the current CI's routing suits to your project, don't use a _remap() method.
$default_controller = "Home";
$language_alias = array('gr','fr');
$controller_exceptions = array('signup');
$route['default_controller'] = $default_controller;
$route["^(".implode('|', $language_alias).")/(".implode('|', $controller_exceptions).")(.*)"] = '$2';
$route["^(".implode('|', $language_alias).")?/(.*)"] = $default_controller.'/$2';
$route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1';
foreach($language_alias as $language)
$route[$language] = $default_controller.'/index';

what the diffence beetween forward and redirect or setRenderView in Zend framework? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between redirect and forward in Zend framework
I'm new to zend framework, when i try to use foward, redirect, setViewRender in controller, what are their diffences?
As the official docs say:
_forward($action, $controller = null, $module = null, array $params = null): perform another action. If called in preDispatch(), the
currently requested action will be skipped in favor of the new one.
Otherwise, after the current action is processed, the action
requested in _forward() will be executed.
_redirect($url, array $options = array()): redirect to another location. This method takes a URL and an optional set of options. By
default, it performs an HTTP 302 redirect.
Read more to understand it better.
i'm pretty sure that a redirect redirects you to a particular page/ controller therefore going through all of the pre view processes including if you can view the page, setViewRender will just output the view you have selected and disregard all of the stuff the controller etc handles. (i haven't used zend for a while however)
_redirect creates a completely new http request, where as _forward simply forwards the request. I realized this when setting a variable in zend_registry, well this might sound a little off the track but when you use _request all the request variables and headers and registry variables are completely reset where as in case of _forward it simply forwards all those things. This is like you can have previously provided information along with some more information in case of _forward.
Well for setViewRenderer I really like this idea, I mean this is something like dependency injection. You dont really need to have a default view, you could provide a new view for the given action. I think you would get the best answer if you look into this.
_forward is an internal redirect. Where as _redirect sends a header that tells the client's browser to go to some other URL, _forward tells the Dispatcher to internally redirect the request somewhere else.
If you consider the normal dispatch order of:
preDispatch()
someAction()
anotherAction()
postDispatch()
Calling _forward at any point in that progression will cause the following steps to not be executed. So if you call _forward in preDispatch(), someAction() will not be called and so on. If you _forward() in someAction() and you are using the viewRenderer action helper to render your views (you are letting the framework choose what view script to render), then no view script will be rendered in someAction().
When the request is forwarded to the new Controller / Module the entire dispatch process will be repeated there.
Note:
If you forward inside someAction() to anotherAction() you must do it like this
return $this->_forward('another');
You should add a return to $this->_forward() or your current Action will continue to execute before forwarding to the other Action.
Also note that the view that will be rendered will be another.phtml
While when doing a redirect, ZF would instruct the browser to load http://example.com/controller-name/action-name as _redirect() sends a header, meaning you create a new HTTP Request and go through the entire dispatch process with it.
Last to render a certain view inside an action use the viewRenderer Action helper:
// Bar controller class, foo module:
class Foo_BarController extends Zend_Controller_Action
{
public function addAction()
{
// Render 'bar/form.phtml' instead of 'bar/add.phtml'
$this->_helper->viewRenderer('form');
}
public function editAction()
{
// Render 'bar/form.phtml' instead of 'bar/edit.phtml'
$this->_helper->viewRenderer->setScriptAction('form');
}
public function processAction()
{
// do some validation...
if (!$valid) {
// Render 'bar/form.phtml' instead of 'bar/process.phtml'
$this->_helper->viewRenderer->setRender('form');
return;
}
// otherwise continue processing...
}
}

Codeigniter multiple controllers vs many methods?

I have a site that has a lot of pages that lye at the root (ex. /contact, /about, /home, /faq, /privacy, /tos, etc.). My question is should these all be separate controllers or one controller with many methods (ex. contact, about, index within a main.php controller )?
UPDATE:
I just realized that methods that are within the default controller don't show in the url without the default controller (ie. main/contact wont automatically route to /contact if main is the default controller ). So you would need to go into routes and override each page.
If all of these are just pages, I would recommend putting them into a single controller. I usually end up putting static pages like this into a 'pages' controller and putting in routes for each static page to bypass the '/pages' in my URLs.
If they are share the same functionality, so they should be in the same controller.
for example, if all of them are using the same model to take content from, so, one controller can easily handle it.
Why in one controller? because you always want to reuse your code.
class someController{
function cotact(){
print $this->getContentFromModel(1);
}
function about(){
print $this->getContentFromModel(2);
}
function home(){
print $this->getContentFromModel(3);
}
private function getContentFromModel($id){
return $this->someContentModel->getContentById($id);
}
}
(instead of print, you should use load a view)
See in my example how all of the function are using the same getContentFromModel function to share the same functionality.
but this is one case only, there could be ther cases that my example can be bad for...
in application/config/routes.php
$route['contact'] = "mainController/contact";
$route['about'] = "mainController/about";
$route['home'] = "mainController/home";
$route['faq'] = "mainController/faq";
$route['privacy'] = "mainController/privacy";
and you should add all of these methods within the mainController.php
You can also save the content of the pages in your database, and them query it. For instance, you can send the url as the keyword to identify the page content
$route['contact'] = "mainController/getContent/contact";
$route['about'] = "mainController/getContent/about";
$route['home'] = "mainController/getContent/home";
$route['faq'] = "mainController/getContent/faq";
$route['privacy'] = "mainController/getContent/privacy";
in this case you only have to create one method named "getContent" in the controller "mainController" and this method will look something like this:
class mainController extends CI_Controller
{
public function getContent($param)
{
$query = $this->db->get_where('mytable', array('pageName' => $param));
// then get the result and print it in a view
}
}
Hope this works for you
The page names you listed should probably be different methods inside your main controller. When you have other functionality that is related to another specific entity, like user, you can create another controller for the user entity and have different methods to display the user, update the user, register the user. But its all really a tool for you to organize your application in a way that makes sense for your domain and your domain model.
I've written a blog post about organizing CodeIgniter controller methods that might be helpful to you. Check it out here: http://caseyflynn.com/2011/10/26/codeigniter-php-framework-how-to-organize-controllers-to-achieve-dry-principles/

Categories