Codeigniter skip login check, define in constructor, for specific action - codeigniter

I defined a login check in my controller constructor method like following code:
if($this->session->userdata('log_in')== false){
redirect(); //function for redirect to login page
}
But I dont want to call this login check for a specific action
(say public function viewProduct())
of the same controller. How can I do that?

You can specify your method name in constructor in if condition like
$method = $this->router->fetch_method();
if($this->session->userdata('log_in')== false && $method !== 'viewProduct'){
redirect(); //function for redirect to login page
}
Now it will be not checked in viewProduct method.

You cannot. You can either run the login check within the individual controller methods or put the view product into it's own controller that does not do the login check in the constructor.
Thinking about this, I suppose you could check the segments within the constructor like this:
if ( ($this->session->userdata('log_in')== false) AND ($this->uri->segment(2, '') != 'view_product') )
redirect(); //function for redirect to login page
}
The uri_segment is explained here: http://www.codeigniter.com/user_guide/general/urls.html#uri-segments
Not sure this is a great idea though. I would do one of the first two suggestions myself. But that is just a matter of preference.
Hope that helps,
Paul.

I think the best way is to pass through method in controller rather do it on constructor. Constructor first run while loading the controller so handling through that is not a good practice. But certain hooks can work for you but you should really follow the standard practice for future coding.

Related

Whats the difference between redirect and this in Codeigniter?

I am new in Codeigniter and it's one of the good frameworks of php. But on some conditions I'm confused. Like this one. If any of you have any clarification about my dough, it's a great help for me.
Offcouse redirects refresh the page and $this not but apart from this I want to know - anyhow both of them used to go to somewhere else on view pages or like in other controller or in same controller to other methods.
But we don't use these side by side because when getting any of them it will go to that page or method without checking the next lines.
In case of a normal difference then have lot's of but I just want to know about the condition of going to next page or method when we use redirect or $this like this -
$this->Function($value); //It's method of same controller.
redirect('Controller/function'); //It's also doing same with page reload.
Thank for looking my problem.
Redirect()
When you will call any function of helper in codeigniter then you can call function directly without using any object. Helper in Codeigniter is collection of functions.
Redirect() method is a part of URL helper in Codeigniter.
For your ref. https://www.codeigniter.com/user_guide/helpers/url_helper.html
So, just load helper using $this->load->helper('url'); or you can also mention in autoload.php file.
$this->Function(); used to call a function from same controller
$this->Function(); used to call a function from same controller
redirect()
While building a web application, we often need to redirect the user from one page to another page. CodeIgniter makes this job easy for us. The redirect() function is used for this purpose.
redirect($uri = '', $method = 'auto', $code = NULL)
The first argument can have two types of URI. We can pass full site URL or URI segments to the controller you want to direct.
The second optional parameter can have any of the three values from auto, location or refresh. The default is auto.
The third optional parameter is only available with location redirects and it allows you to send specific HTTP response code.
Redirect means jumping to another function mentioned in the redirect method.
$this->Function($value); => jumping to another function and you can execute the code of the same function as well as pass the value back by returning value.
When you send request to codeigniter generally CI controller gets called and then function which is mentioned in uri segment. like below... So this will be another request.
redirect('Controller/function'); //It's also doing same with page reload.
But when you have to call another function within the same request then you can use below approach
$this->Function($value); //It's method of same controller.
This will execute the given function and return the value within same request.

Single method to handle post or loading view in laravel

I am trying to understand how POST routing will work. I have a method defined, signup(), and I want to use the same method to detect if the user wants to sign up (so load the signup view) or if the user already in the signup view (form) and posting his details to register.
Can this be done in one function in laravel? if yes, then how? Is this controlled by Routes and if yes, can someone please clarify this with an example?
Laravel documentation is really confusing for beginners.
Thanks in advance,
While this is possible but it's not recommended way to do that, you should keep your routes separated from each other (using GET and POST) and should use different methods as well. Basically any form submission should use POST request (using POST HTTP method) and to show the form just use a GET method but anyways, you can do it (what you have asked for) like this way:
// Declare the route
Route::post('signup', 'UserController#signup');
Now in your signup check for the submit button to make sure that, the form is submitted, so if the input submit is available in the $_POST array then the form is submitted otherwise, it's not submitted but an empty form was presented to the user or a failed validation redirect happened. Maybe something like this:
public function signup()
{
if(Input::has('submit')) {
// It's a submission, so Validate submitted Form data
// if invalid then redirect back with inputs and errors
// Otherwise save it
}
else {
// show the form
return View::make('user.signup');
}
}
Don't do it
This is just an idea but, it's a bad idea, just think about what happens if you have errors on your form and you want to redirect back then the whole thing would become messy, the controller method will become totally unmanageable after a while because it does many things while it should have only one specific responsibility.
I have this practical experience, because, I used to think that, if I can use one function for loading and saving and even also updating then it would be smart but to be honest it was stupid and obviously it's an anti-pattern, not the best practice, against KISS (Keep It Simple Stupid) principle. This kind of coding is a bad idea and you'll suffer for it in future and you would not dare to touch the code thinking that if you brake anything because you'll be confused by your own code.
Just use separate methods to show a form and save submitted data, Also check this on slideshare.
Yes, you can use one route to do it:
Route::any('signup', 'SignupController#signup');
Or two routes pointing to the same url:
Route::get('signup', 'SignupController#getSignup');
Route::post('signup', 'SignupController#postSignup');
In both cases you'll need a controller:
Here it is with all related methods:
class SignupController extends Controller {
// This one is for Route::any()
public function signup()
{
if (Input::has('email'))
{
// create your user
}
return View::make('signup');
}
// those two are for the second option
public function getSignup()
{
return View::make('signup');
}
public function postSignup()
{
// create your user
}
}

Codeigniter - custom routes

Lets say I have a controller 'standard' with an action 'main'.
If I go to www.myapp.com/standard/main it will invoke the main action in the standard controller.
Now if I want to change the URL I go into the routes.php and set sth like the following:
$route['welcome'] = "standard/main";
Now I can visit www.myapp.com/welcome and it will invoke the same action.
However it is still possible to visit www.myapp.com/standard/main. I now have two routes which lead to the same controller action.
Is this the usual way or should I somehow disable the now unwanted www.myapp.com/standard/main route? If so, how would I do that?
Thanks in advance.
That is completely for you to decide the default behavior. If you decide to disable the original url, you can write something like
$route['standard/main'] = 'standard/404';
Or any custom location, it depends on your project and how you wish it should look like, for example you can 'block' any method from being accessed directly:
$route['standard/(:any)'] = 'standard/404';
But bear in mind, if you route like you did $route['welcome'] = "standard/main";, then you should always remember that the function $this->uri->segment(n) will show different values, for example if I will go to url yoursite.com/welcome/123, the value of $this->uri->segment(2) will be 123, but if I visit the original URL yoursite.com/standard/main/123, it's value will change to main.
Bear that in mind and decide for yourself!
Assuming that this is a common structure you'll be using, for each action, you can check the segment's in the URL and then redirect appropriately. In the case of going from standard/main to welcome, you would have the following:
class Standard extends CI_Controller {
public function main() {
if($this->uri->segment(1) == 'standard') {
redirect('welcome', 'location', '301');
}
}
}
This would then check the first segment in the URL and if it sees that you've come to this URL, redirect you to the appropriate route. This can then be applied to each action you want to do the same thing for. Supplying a 301 signifies a permanent redirect.
Update
Just found a similar (the same?) question: Only allow URL's specified in routes to be seen in Codeigniter

Magento - Passing a session variable to a page called via _redirect()

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.

Attempting to use _remap to create page controller

I'm trying to create a default page controller for a site with urls like http://www.example.com/about. So, if there isn't an 'about' controller, then go looking for a page with that url string in the database.
I've set the 404_override to my 'page' controller and am using the _remap() function to determine where to go next, either load the homepage (the page controller's index() method) or load a page.
However, as it stands right now if I use a different controller (product, in this case) with a method in the path (http://www.example.com/product/widget, which doesn't exist) I am being served the index() method of the page controller.
I thought the problem comes from the way I'm checking if the requested page is the homepage in my _remap() so I added an echo to the beginning of my remap to see if it mattered. The _remap() doesn't appear to be called. Instead, in attempting to handle the 404_override CI just shows the index method.
Any ideas how I can accomplish this more effectively?
public function _remap($method)
{
echo 'Method '.$method;
if($this->uri->segment(1) == null)
{
// $this->index();
} else {
$this->view();
};
}
I seem to have found a workable solution in this blog post: http://pinoytech.org/blog/post/codeigniter-route-everything-except-these-controllers
Using a regular expression in the route definition allows for other controllers (product, order, etc.) to be ignored while still sending everything else to the page controller.
$route['^(?!product|order|misc_controller)\S*'] = "page/$1";
Haven't tested it out just yet, but as far as I can tell it should work swimmingly.

Resources