Codeigniter - change url at method call - codeigniter

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.

Related

How to return to another page after finishing process in Laravel?

This is a little bit hard to understand even the title I put. Sorry about that I just do not know how to clearly explain this, but I will try...
So for example I have a controller and inside that controller I have a function which return the data in the table of my database. then in the last column of every row, I make view,add,edit,delete options as links. When a user clicks on the add for example, they will redirect to an add page. After they submit the form of the add page. they should be redirected to the first page that return the data from the table. but the problem is, the variables of foreach loop in the first page do not got recognized by laravel anymore. because they do not got processed since the route does not goes to the controller and to the function that return the data instead it goes to add function.
So I want to know is there anyway to solve this? If you could provide sample code, I would appreciate a lot thanks
From your explanation, I believe the code to go back to the original page after adding, editing etc is simply return redirect()->back(). This will take the user back to the previous page. As for data continuity, one approach would be considering using sessions. They save data globally and can be accessed from any controller once saved. To do this, simply save the data with session(['session_name' => $data]) and to retrieve the data use session('session_name'). Let me know if this helps!
If you want ti redirect after something like a login or an activation process you can do it with something like this:
return redirect()->to('login')
You can specify the path from your web.php file as you can see in my example in 'myPath'
As #DerickMasai correctly pointed out it is better to use named routes instead of hard coding the path itself.
Naming a route can work like so:
Route::get('/login', [LoginController::class, 'index'])->name('login');

Form from another model in a view

So I'm trying to extend the Blog tutorial adding some comments:
Post hasMany Comments
I want to display the add comment form in the same view as the 'post view'. Thing is I don't know the best way to get this approach. I thought about three ways:
Creating a function in Comments Controller to handle the data.
Creating a function in Post Controller to handle the data.
Deal with the data in the same function that deals with the post views.
The main problem with the two first 'solutions' is that the validation errors doesn't show up in the form unless I do some messy hacking of saving the invalidated field in a session variable and then parsing the variable on the beforeFilter callback, like this:
function beforeFilter () {
if ($this->Session->check('comment_error')) {
$this->Post->Comment->validationErrors = $this->Session->read('comment_error');
$this->Session->delete('comment_error');
}
}
What I basically do is adapt the invalidated fields to the actual view and allow it to show properly. This works really well, but it seems so ugly to me. What would be the best approach?
Another related question: should a controller reflect a view? I mean on that example, I thought about only having a Comment Model and dealing with all the data in the controller where's the form to add a comment (even though it's in the Post Controller).
Sounds like you're looking for the Mutlivalidatable behaviour: http://bakery.cakephp.org/articles/dardosordi/2008/07/29/multivalidatablebehavior-using-many-validation-rulesets-per-model
This allows you to define more than 1 validation ruleset per model. Use your controller to determine which one to apply upon posting something.
P.S. I have only ever used this on a Cake 1.3 project, not sure if it'll work on 2.0.
I see it this way:
Under every post there is an input box "Add comment" with a button to submit.
After submitting some text a form redirects to comments_controller where the comment is saved with this post_id, body, author, date etc.
After the comment is saved and all the logic is done it takes you back to the post.
Under each post there are all related comments displayed (having the same post_id sorted by date or whatever).

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.

Use CodeIgniter form validation in a view

I have footer view that's included on all my pages which contains a form. I would like to be able to make use of CI's form validation library to validate the form. Is that possible?
Currently the form posts back to the current page using the PHP_SELF environment variable. I don't want to get it to post to a controller because when validation fails it loads the controller name in the address bar, which is not the desired behaviour.
Any suggestions gratefully received.
Thanks,
Gaz
One way, whilst far from ideal, would be to create a "contact" function in every controller. This could be in the form of a library/helper.
CI doesn't natively let you call one controller from another, although I believe there are extensions that enable this.
Another option would be an AJAX call instead, which would allow you to post to a generic controller, validate etc whilst remaining on the current page.
In this use case, I would definitely go for an AJAX call to a generic controller. This allows you to show errors even before submitting in the origin page.
Another way (slightly more complex), involves posting your form data to a generic controller method, passing it a hidden input containing the current URL.
The generic controller method handling your form can then redirect to the page on which the user submitted the form, passing it the validation errors or a success message using flash session variables: $this->session->set_flashdata('errors',validation_errors()) might do the trick (untested)
The good thing about this is that you can use the generic form-handling method for both the ajax case (suppressing the redirect) and the non-ajax case
AJAX would be best, just like everyone else says.
I would redirect the form to one function in one controller, you could make a controller just for the form itself. Then have a hidden value with the return URL. As far as errors go you could send them back with flashdata.
Just remember to never copy paste code, it a bad practice and guarantees bugs.
//make sure you load the proper model
if ($this->form_validation->run() == FALSE){
// invalid
$redirect = $this->input->post('url');
$this->session->set_flashdata('errors',validation_errors());
redirect($redirect);
} else {
/*
success, do what you want here
*/
redirect('send them where ever');
}

Redirect CI problem

I'm kind of new with CodeIgniter and I'm still learning (a lot).
So I have a view and when I submit a form I 'call' the controller by surfing to the right URL dynamically e.g. site/delete
class Site extends Controller {
function index(){$this->load->view('...')}
function delete() {
$this->site_model->delete_row();
$this->index();
}
}
Now when that action is done (deleted the row) I'm calling $this->index(); to redirect to my initial page (which is good) but my url stays: site/delete . I want my URL to be ../site/index (or without the /index)
Any help would be appreciated :-) .
So far I found something to solve this:
instead of:
$this->index();
I'm using:
redirect('site');
Does anyone know this is a good practice?
Redirect is what you should use.
In the user guide:
http://codeigniter.com/user_guide/helpers/url_helper.html
they use it after checking if a user is logged in. Depending on if they are or not, they redirect to a different place.
Also, note that any code after the redirect won't run. Make sure and redirect after you've done everything you need to.
My preferred method is to have actions like that handled by the same method that will be seen by the user afterwards.
What if you go to /site/delete afterwards, as a user? It will either have to detect and throw a error (show a message) or redirect to an appropriate page. /site/delete has no meaning.
For example, if a user would normally see an overview after deleting, then my form will be posted to /site/index; with index quickly checking for the condition and calling _delete() in the same controller, before doing its normal work.
That way, if the user refreshes the page, or presses 'back', things should look consistent to them.
Another example would be that /settings/edit would post to itself - this means that it can act on the post and show any output (e.g. validation errors). It means there's no /settings/do_edit location on my site, and also means that the user can go back to /settings/edit safely, and see a form for editing their settings.
I suppose this is a subjective take on a perhaps objective question, and I would encourage feedback on my view, but it's my way of avoiding the problem you have asked about.
$this->index();
Call of function in a function simply execute the functionality within that function.
And url never changed.
for changing the url you should use.
redirect ( base_url().'site');
but you should load url helper in constructor.

Resources