How do i page using forms with the Codeigniter framework? - codeigniter

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.

Related

Codeigniter - change url at method call

I was wondering if the following can be done in codeigniter.
Let's assume I have a file, called Post.php, used to manage posts in an admin interface.
It has several methods, such as index (lists all posts), add, update, delete...
Now, I access the add method, so that the url becomes
/posts/add
And I add some data. I click "save" to add the new post. It calls the same method with an if statement like "if "this->input->post('addnew')"" is passed, call the model, add it to the database
Here follows the problem:
If everything worked fine, it goes to the index with the list of all posts, and displays a confirmation
BUT
No the url would still be posts/add, since I called the function like $this->index() after verifying data was added. I cannot redirect it to "posts/" since in that case no confirmation message would be shown!
So my question is: can i call a method from anther one in the same class, and have the url set to that method (/posts/index instead of /posts/add)?
It's kinda confusing, but i hope i gave you enough info to spot the problem
Cheers!
Use the redirect() in conjunction with CodeIgniter's Flash Data, or opt for AJAX.

How to load the layout at runtime in Magento?

I know that we can design the layout in *.xml then in the action just invoke loadLayout, and renderLayout to render the blocks/views.
But, I have a question is:
- How can I load the layout at runtime?
If we have an action which does not really design its layout and will be decided how to render at runtime.
You can please consider the answer from the question for more clear.
Writing a new answer because it seems that you actually DO still want to render, you just want to render a different route's layout XML updates. I believe the _forward() method from Mage_Core_Controller_Varien_Action will allow you to do what you are describing with the least amount of pain.
You should add your action controller directory ahead of the catalog directory, create a ProductController with a viewAction, and check customer is not logged in - in this check you would call $this->_forward('customer','account','login');.
This approach though is going to require more effort in order to be usable, as I imagine that you want the user to be sent to the product page upon login. Have you seen Vinai Kopp's Login Only Catalog module? It should do this for you.
loadLayout() and renderLayout() just execute block output method toHtml() (usually) and take the resulting strings and apply them to the response object via appendBody(). In an action controller you can just call $this->getResponse()->setBody('response string'). How you build the string is up to you.
You can also use Mage_Core_Block_Flush to immediately send output to the browser without using the response object.

How to get error messages from model

Say you have a User model. The controller is attempting to create a new User. Should the controller check that the username is valid, and the password is long enough, and the first and last name are filled out, etc? Or should you pass all that data straight to the User model via a Create method? The Create method would then return a true on success, or false on failure?
If it's the latter (and I think it is), how do the error messages get sent back to the controller (so they can be displayed in a view)? Should you pass an errors array to the Create method which the model augments? Or should the model keep an internal store of errors, with appropriate accessors? I don't like either method...is there a better way?
These errors don't seem exceptional, so I don't think exception handling is appropriate.
Edit: I'm using PHP for this project, but I use Python too.
For the first question, the model should do the verifications (and use some form of error handling to notify the controller and view that errors did or did not occur). For the second, it depends on what programming language / framework you are using... What are you using?

Codeigniter - reusing controllers?

I am trying to code my first codeigniter project. I have a login controller which basically filters the data inputed and calls a model function that checks if the user is found in the database.
What I am trying to do is reuse this controller on the index page. So basically I want to be able to do user login on the index page or on the normal controller page (index.php/login/) without code duplication.
I'm sure there is an easy way to do this, but I'm not sure what the best solution is. Make it a library?
Thanks!
For this I would simply make the form in your view post to the login controller.
As a more generic way to share code and logic throughout your application, take a look at this article:
CodeIgniter Base Classes: Keeping it DRY
You basically give each of your controllers a "type". Being logged in could be a criteria of one of your base controllers, which saves you trying to directly access any of your controllers which is bad mojo.
You can try creating a form on the index page and submit it to index.php/login/. This way you won't need two entry points.
Just do the same as you have done for the login View, specify the same action attribute of the form to the index View, and it will be sent to the same login controller with no need to create the two login controllers. You might want to append a query string in the action attribute of the form to distinguish from which View the request has come.

Getting the url of an aspx page using the page type

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

Resources