I think this is one of the more complex tricks to get right and therefore I have decided to elicit the help of the very knowledgeable people on StackOverflow. My scenario is as follows: I have two entities, a user and an account. A user is always linked to an account upon registration (and depending on the type of user, might be linked to more than one account. Upon registration the function saveUser() is called (via ajax from frontend) and the submitted form data is retrieved from the Request Object. This data is then passed to the function saveAccount($data) (which is called in the saveUser() function) in the form of a parameter and the account is created (sometimes called more than once with different data sets to create various accounts), which is linked to the user.
Now I want to create an account from my admin panel without creating a user, so I want to call saveAccount($data) directly via ajax (from frontend) and pass the form data to it as a PARAMETER (instead of retrieving it in the function via the Request Object), so that I can use the same saveAccount($data) function and that I do not have to create a saveAccount() which works the the Request variable. Does this make sense? Is this possible? If so, how would I go about doing this?
I did not post any code, as I did not see the need for it, this is more a conceptional problem, but if you require the code that I have thus far or if anything is unclear I will be happy to elaborate.
There should not be any saveAccount method, you just rely on relationships between entities, i.e. on a setAccount method, or to a addAccount one in case you need to add an entity to a Collection.
Then Doctrine will take care of saving and persisting everything.
For saving data, I would always rely on a RESTful interface [which you can create easily via FOSRestBundle], and send everything via ajax no matter what; you'll end up with a smoother interface and more maintainable code.
For instances where a controller function can be called either via AJAX with form data or internally by a another controller function the following solution works:
public function saveAccount($data = null)
{
if (empty($data)) $data = $this->getRequest()->request->all();
...
}
Then you can pass an array to the controller function in the same format as your form data array and it will use that data if passed to the function, otherwise it will retrieve the REQUEST (form) data.
Related
help me! I am a php rookie and i am confused with the php request.
Working on MVC structure for view, I created a HTML form, and on form submit i want to do call two different methods sendMail() and validateData() available in two different controllers (php file) - say one in process.php and another in register.php .
On form submit first I want to validate the data and save data to database using validatedata(). Then I want to send a verification mail to the user using sendMail().
To handle the request (click event) I am using jquery ajax. Ajax takes a single URL for posting data to the specified URL. So how can I make two different URL requests in a single Ajax call, or say how can I call both the methods in a single Ajax call?
Please suggest me what i should do to solve this issue?
thanks in advance.
A controller should handle an entire request.
So if the user makes (for example) a request asking to create a new user account then a single controller should:
Validate the data the user has sent to make sure it is what is required before creating an account
Create the account in the database
Send the email
Return a response saying if it worked or if there was an error
So you'll end up with something like
{
$errors = validateData($_POST);
if ($errors) {
echo generateErrorPage($errors);
exit;
}
$result = createUserInDBAndSendEmail($_POST);
showSuccessPage($result);
}
(That's very rough and ready for the sake of example).
Don't divide the steps you need to do to complete the task up between different controllers. Then you only have one URL to worry about.
You can divide the functions up between different files and then include them.
The complete process for creating a user might require additional feedback from the client, e.g.
Client makes a request to the CreateUser controller
Server creates a user in "unconfirmed" state, sends email to the user and returns an HTML page telling them to check their email
User clicks a link in the email to make a request to the ConfirmEmail conroller
Server changes the user to "confirmed" and returns a logged in homepage with a welcome message
… and in that case it would have multiple controllers since you need the user to make two different requests.
I have a controller which handles the adding of records to a database. Sometimes these records require a couple of passwords to be entered, to "sign the record". Therefore, when the form is submitted, it is passed to a function in the controller called "getSignatures." This will load a view with inputs for the passwords needed. The users will then enter their passwords to "sign the document". This will then be passed to a function in the controller called "checkSignatures," which will call a function in the model to check the passwords.
However, I still need to pass through or save all the data from when the form is submitted.
I have tried using a global variable to save the form data, but when the checkSignatures function is called, it's called through a new controller. I also tried passing through the form data to the view, saving it in a hidden input and then passing it back through post but you can't save an array in a hidden input.
Any ideas would be great, and sorry for the long-winded question.
Try using sessions as described here. In particular you should look at CodeIgniter's flashdata.
Sessions will be stored on the server for the entirety of the user's browsing session. This will let you access the data again. Flashdata is deleted after the next page load so they don't stick around for long.
I'm pretty new to Symfony2 and am just wondering what would be the preffered way of doing this.
I have lots of admin actions that involve receiving form data and processing it. Naturally, when processing is finished, controller action sends return $this->redirect($this->generateUrl('.....'));.
Now since I have made a JavaScript that submits forms via ajax if browser supports it I need to modify my controller actions to return Response object containing json array but only if request was sent via ajax.
Is it possible to recognize if request sent to controller is AJAX request?
Where in directory tree is the preffered place to place class named ResponseHandler which would do the redirecting or returning json array based on type of request ? I realized Symfony2 is very strict about these things so I want to get it right from the start. Maybe there is even already bundled solution for this in it?
Update
I figured out I can use $this->getRequest->isXmlHttpRequest() in controller.
Question 2 still stands.
Where in directory tree is the preffered place to place class named ResponseHandler which would do the redirecting or returning json array based on type of request?
If you do an AJAX request you store the data in an parameter, a POST or GET parameter. You can access this parameter in the controller with:
// ...
public function finishAction()
{
// if you use a GET request
$data = $this->getRequest->query->get('my-get-parameter');
// and if you use a POST request
$data = $this->getRequest->request->get('my-get-parameter');
// ... do something with the data
}
However to answer your question:
The symfony core framework uses the Event Dispatcher component to trigger and attach events. The events are triggered everywhere in the Symfony code. You can attach a class to an event and when that event is triggered, you can change it. That way, you can modify the Response object.
Events that are thrown in the code can be found in a *Events class in that component. In this case, we want the REQUEST event. Read more on the event dispatcher and how to attach events in the documentation: Event Dispatcher Component and Symfony2 Framework specific documentation.
I realized Symfony2 is very strict about these things
Symfony really isn't strict about your directory structure. It delivers a default Standard Edition with the recommend structure, but you can change it to make it yours. And if a class is written in the PSR-0 standards symfony will load alle classes you need.
i have a user class with a function to add a user.
i also have a form that triggers an ajax call on submit which passes a query string for the username and potentially other information to the controller.
everytime the controller gets called via ajax, it creates a new instance of my user class and calls the add user function by passing the query strings as parameters.
is there a way where i can output an array of usernames that have been submitted without storing it in a sessions.
I use a global variable to indicate I'm currently in AjAX mode. So when you call the AJAX controller set a global variable.
Then just skip the add user function by checking to see if the global variable is defined.
Your options are to store it:
In a session.
In a file.
In a database.
PHP is not a persistent service, and will not remember anything between requests other than what has been stored either in a session, or in an external store.
All my previous projects have had this workflow on Contact pages
User submits form
Controller gets $_POST details
Controller validates details (and sets error messages if necessary)
Controller sends email
Controller redirects to thanks page
Is this the standard workflow?
I used to validate everything in controllers, and then did some more reading and they recommended against it. Therefore, should I send the $_POST details to a helper type object and let it do all the work (validation/sending)?
In controller we should only check validation. The main validation should be on model before operations with DB.
The controller file need to check & validate the user input data.
After getting & accumulating all the data, it needs to transfer the data to the Model file for checking with the database (if needed) & then need to do some other works from here (like setting sessions / cookies, or sending mails, or firing hooks, ...). However, the control must come back to the same controller method, as all the previous model functionalities must be fired by a method call, from the same controller method.
The proper view method must be called now, and then the output must be rendered to the console.
Hope it helps.
Validation is typically performed in the Model, not in the Controller.
This is because data structures are usually defined in the Model and it is best to compare the acquired data immediately before manipulation (i.e. inserting into a database, etc.).