For my Codeigniter (v 3.1.7) project, i create debug menu (like prestashop) with all informations of the login user, error of the page... to debug quickly the page.
So, i want to call the name of the controller and the name of the function.
If i'm on the page "login" i want to display:
Controller: Account
Function: Login
I find on this post i tips for my problem but we use Url REWRITING and the name of the url is not the real name of the controller.
If your CI version is below 3, you have to use like that:
$this->router->fetch_class();
$this->router->fetch_method();
and if your CI version is 3 or above. These methods are deprecated.
$this->router->fetch_class();
$this->router->fetch_method();
You can access the properties instead.
$this->router->class;
$this->router->method;
See codeigniter user guide
URI Routing methods fetch_directory(), fetch_class(), fetch_method()
With properties CI_Router::$directory, CI_Router::$class and CI_Router::$method being public and their respective fetch_*() no longer doing anything else to just return the properties - it doesn’t make sense to keep them.
Those are all internal, undocumented methods, but we’ve opted to deprecate them for now in order to maintain backwards-compatibility just in case. If some of you have utilized them, then you can now just access the properties instead:
$this->router->directory;
$this->router->class;
$this->router->method;
You could use the URI Class to get that information:
$this->uri->segment(n); // n=1 for controller, n=2 for method, etc
Related
I have the need to pass a URL to Magento, where it should redirect the User after completing the logout. To store it, I do the following:
$BackTo = Mage::app()->getRequest()->getParam('backto');
if(!empty($BackTo)) {
Mage::getSingleton('core/session')->setBackTo($BackTo);
}
When needed, I retrieve the URL using Mage::getSingleton('core/session')->getBackTo(). The issue is that, while this works well on login, it doesn't work on logout (where it's most needed). I can store the session variable, I can also immediately retrieve it, but, when I am in logout.phtml, where the redirect JavaScript is located, such variable is set to null.
I suspect that the redirect performed by Magento upon logout has something to do with this "disappearing" session variable, but I can't say for sure.
For completeness, here is the relevant code (there's more code than this, but they are mainly auxiliary functions, which don't get called on logout).
Account Controller
class MyPackage_Redirectplugin_AccountController extends Mage_Customer_AccountController {
/**
* #see AccountController:logoutAction()
*/
public function logoutAction() {
$this->_getSession()
->logout()
->setBeforeAuthUrl(Mage::getUrl());
// Store the "back to" URL in a session variable
$this->StoreBackToURL();
$this->_redirect('*/*/logoutSuccess');
}
protected function StoreBackToURL() {
// Store the value of the "backto" argument, if it was passed
$BackTo = Mage::app()->getRequest()->getParam('backto');
if(!empty($BackTo)) {
Mage::getSingleton('core/session')->setBackTo($BackTo);
// At this point I can see the correct value stored in the session variable
}
}
}
Logout.phtml
// The following command returns null
$redirectURL = Mage::getSingleton('core/session')->getBackTo();
Thanks in advance for the help.
Update 12/09/25 - Found a workaround
Since I couldn't find a way to pass a session variable to the logout page opened by redirect, I chose an alternative way: I'm passing it via the URL. Specifically, I implemented a logoutAction() which calls $this->_redirect('*/*/logoutSuccess', array('myvar' => $MyValue));.
In the template, where I have to do the redirect, I simply read such parameter using Mage::helper('core')->urlDecode(Mage::app()->getRequest()->getParam('myvar'));.
I'm aware that there might have been better ways to implement the whole thing, but I needed a bug fix solution and this does the job. Thanks to all people who answered.
The cleanest option which I see (no controller rewrite necessary!) is to observe the dynamically-dispatched controller_action_postdispatch_customer_account_logout event - see the relevant line fromMage_Core_Controller_Varien_Action::postDispatch(). The postDispatch() method is called after the controller action completes.
Example observer method:
public function logoutRedirect($obs)
{
$redirectUrl = Mage::getUrl(/* url args */);
$obs->getControllerAction()->getResponse()->setRedirect($redirectUrl);
}
Doing this will redirect the user to the desired URL directly upon logout meaning that the logoutSuccess page with the JS redirect will not be accessed.
If the desire is to have the logoutSuccess page render as normal, but redirect to a different URL, this can be achieved a couple of ways:
1. By creating a custom template
2. By creating a custom template block class, overriding the getUrl() method to retrieve the URL of your choice, and assigning that as block to render in the content area (by removing or displacing the customer_logout block) in a custom layout XML update file.
just observe this event customer_logout, and when event call method you save the session key on database.
Learn more: http://www.magentocommerce.com/wiki/5_-_modules_and_development/reference/events
http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method
GL.
Update 12/09/25 - Found a workaround
This workaround has also been posted in the question itself.
Since I couldn't find a way to pass a session variable to the logout page opened by redirect, I chose an alternative way: I'm passing it via the URL. Specifically, I implemented a logoutAction() which calls $this->_redirect('*/*/logoutSuccess', array('myvar' => $MyValue));.
In the template, where I have to do the redirect, I simply read such parameter using Mage::helper('core')->urlDecode(Mage::app()->getRequest()->getParam('myvar'));.
I'm aware that there might have been better ways to implement the whole thing, but I needed a bug fix solution and this does the job. Thanks to all people who answered.
I'm using the Codeigniter framework and am in the process of creating a registration form. The registration process is completed in multiple steps- for which I've created different views.
What I have a problem with is making the controller read that I've continued to a new step. I tried solving this by posting the form to index.php/controller/2 but as I reach the page I get a 404 error stating
The page doesn't exist.
I've loaded the URI helper so I don't quite understand where the problem lies.
All help is very much appreciated
By submitting the form to index.php/controller/2 you're effectively saying
Load /application/controllers/Controller.php
Instantiate class Controller
Run Controller::2()
I suspect you don't have a method named 2, and you want to pass two as an argument to a method which handles step 1. Which might be /controller/register or similar.
You need to submit your form to index.php/controller/method/2 and inside method check which step you're on using $this->uri->segment(2)
Ideally, create a different method for each step as it'll better separate the logic. For example
class Registration {
function step_1() {}
function step_2() {}
}
Which will allow you to call index.php/registration/step_1/ and index.php/registration/step_2/ for example.
You may also wish to use the Session class to set variables indicating which stages are complete to prevent people skipping to other stages by typing in the URL.
I see people using Html.ActionLink() and Url.RouteUrl() etc. etc.
But surely this will lead to a maintenance nightmare if routes need to be redesigned?
How are people organising the generation of URLs in a typesafe and manageable way?
Strongly typed URL generation via lambda expressions was available for a period of time during the MVC 1.0 beta timeframe. It was removed since the MVC architecture does not actually have a 1-to-1 mapping between action names and controller method names. See this Phil Haack blog post for details.
It is of course still possible to do it, and assuming you're not using action names that differ from method names, it should work fine.
You can use T4MVC to generate typesafe checks at compile time for your MVC urls.
T4MVC analyses your Controller classes, and generates code that will generate typesafe url's.
Instead of
#Html.ActionLink("New customer", "Create", new { Controller = "Customer", orgID = orgID })
You can use code like:
#Html.ActionLink("New customer", MVC.Customer.Create(orgID))
If you want to call a action you use the Html.ActionLink(). This will create a <a href="..." ></a> hyperlink to chosen action.
If you want to create a url and use it not for a hyperlink, you can use the Url.Content() or the Url.RouteUrl(). The content accepts a string and gerenates a safe url. The Route url takes a route object.
I switched from Intelligencia's UrlRewriter to the new web forms routing in ASP.NET 4.0. I have it working great for basic pages, however, in my e-commerce site, when browsing category pages, I previously used querystrings that were built into my pager control to control paging and now am not sure how to handle this using routing.
I defined a MapPageRoute as:
routes.MapPageRoute("cat-browse", "Category/{name}_{id}", ~/CategoryPage.aspx");
This works great. Now, somebody clicks to go to page 2. Previously I would have just tacked on ?page=2 to the url. How do I handle this using web forms routing? I know I can do something like:
http://www.mysite.com/Category/Arts-and-Crafts_17/page/2
But in addition to page, I can have filters, age ranges, gender, etc.
Should I just keep defining routes
that handle these variables like
above?
Should I continue using querystrings
and if so, how do you define a route
to handle that?
The main reason to use url routing is to expose clean, user-and-SEO-friendly, URLs. If this is your goal, then try to stick to it and not use querystring parameters. Note: I don't believe we need to completely ban the use of querystrings and, depending on your situation, you may decide it best to use querystring parameters for parameters that are not used frequently, or where no real value is added by making the information more semantically meaningful.
So here's what I would do:
Define a catch-all for all your other parameters:
routes.MapPageRoute("cat-browse", "Category/{name}_{id}/{*queryvalues}", "~/CategoryPage.aspx");
In /CategoryPage.aspx, access the router parameter and then parse as appropriate:
Page.RouteData.Values["queryvalues"]
Instead of using the syntax of Arts-and-Crafts_17/**page/2/age/34** for these parameters, I perfer to use the following syntax: Arts-and-Crafts_17/pg-2/age-34/
If you do this, the catch-all parameter 'querystring', will equal pg-2/age-34. You can now easily parse this data and add each name/value to the page context. Note that you will need to do something along these lines since each of these parameters are optional on your site.
You can take advantage of C# 4.0 named and optional parameters. Please have a look at this example from haacked
If you are using a lower version of the framework, you can also use code from the link above. But instead of declaring the method as
public ActionResult Search(int? page=0)
{}
you can declare it as
public ActionResult Search(int? page)
{
if(page == null)
{
page=0;
}
}
HTH
I'm using a web application project.
I have a folder in my web root called Users and in the folder I have a page called UserList.aspx
What I want to be able to do is type in Response.Redirect(Users.UserList.URL)
What I reckon I can probably do is create a class that extends Page and add a static property called URL that calls MethodInfo.GetCurrentMethod().ReflectedType (I think this works haven't tested) and then have that convert Users.UserList -> ~/Users/UserList.aspx
The problems with this method that I know of are one I need to go through every page and make it extend the base class and it doesn't work with any pages that contain a '-' character.
The advantages are that if pages are moved around then there aren't any broken links (Resharper gives out when there is a Page with the wrong namespace).
Also then every individual page that takes query string params could have a static method so that if I want to add/remove params I can see what uses those params etc.
Also if I want to call that page I don't have to check the name of the params e.g. UserId userId, Id or id. So that would look something like Users.ViewUser.GetUrl(1) -> ~/Users/ViewUser.aspx?UserId=1
So the question is: Is there a better way of doing this? Or is this a bad idea in principal?
You could just create an extension method for the base Page class that does what you are thinking. That would avoid having to go back and modify the base class for all your pages.
There is a better way. Create a traffic cop that knows about paths. Then if paths change, your data model changes or other stuff you just change that one place. Plus you could have read from a config file and make changes at run time.
Thus your call looks like this:
Repose.Redirect(TrafficCop["Users.UserList"].URL)
or some other way if you don't like the syntax.
The MethodInfo.GetCurrentMethod().ReflectedType doesn't work so I came up with another method of doing this using generics.
Instead of Users.ViewUser.GetUrl() or Users.ViewUser.URL it's GetUrl()
For a page with parameters it's still Users.ViewUser.GetUrl(1), it isn't ideal because they should both have the same way of being called but better than strings I guess.
Going to leave the question open for a while just in case.
edidt: I think I will actually just create another method called GetUrl(String getQuery) because if I have two parameters that are of the same type it doesn't work very well.
further edit: I found out how to do exactly what I want to do.
created a class called BasePage:Page where T : Page
on that are the static methods redirect and geturl
each page inherits from the base page as follows: MyPage:BasePage
Any page can redirect to that page by using the command MyPage.Redirect();