validating email address using AJAX - symfony1

Is there an easy way to check an email address is valid using Ajax? I'm using the sfValidatortEmail widget currently and this only shows an error message on submitting the form.
Thanks

I'm assuming you know how to write ajax requests. In the action you'd have something like
if ($request->isXmlHttpRequest()) {
// handle ajax check
try{
$validator = new sfValidatorEmail();
$validator->clean($request->getParameter('email'));
// good to go
} catch(sfValidatorError $e){
// invalid email
$this->getResponse()->setStatusCode(400);
}
} else {
// handle normal post
}

You'd need to add some Javascript/Jquery to fire an Ajax request to check the email, possibly linked to when the user clicks out of the email input box (blur function). This would be separate from your form class (assuming that the form has other elements too), but you could use the same action to handle the request if you wish:
if ($request->isXmlHttpRequest()) {
// handle ajax check
} else {
// handle normal post
}

Related

Symfony Form reset after submit

I have a very simple form created with createFormBuilder providing one simple text field only (there is no entity attached to the form).
When the form is submitted I do some logic and then unset form and formData as suggested in many posts to this topic if you want the form to be reset after submitting.
There is some additional action by simple ajax-requests that mainly initiates some UI stuff - not touching the form itself nor reloading the page.
Everything works fine except that the form apparently just doesn't want to be reset - meaning: Whenever the page reload button in the browser is pressed the standard browser dialog appears that asks if you want to submit the form again. And when you do the last value typed in BEFORE the last render call is submitted.
The template kw.html.twig is straight forward - mainly some UI stuff the form rendering and a bit jquery for handling ajax. Nothing special there.
I can't figure out why this is happening - I just want a clean form on any request. Which I thought I get when unsetting thing like in the sample code below.
/**
* #Route("/kw", name="show_kw")
*/
public function showKwAction(Request $request)
{
if($request->isXmlHttpRequest()) {
if( $request->getMethod() == 'POST' ) {
// do some logic...
return $this->json(array('kw_success' => true));
}
}
$kwData = array();
$kwForm = $this->createFormBuilder($kwData)
->add('kd', TextType::class)
->getForm();
if( $request->isMethod('POST') ) {
$kwForm->handleRequest($request);
$formData = $kwForm->getData();
// do some logic with formData...
unset($kwData);
unset($kwForm);
$kwData = array();
$kwForm = $this->createFormBuilder($kwData)
->add('kd', TextType::class)
->getForm();
}
$templateData = array(
'kwForm' => $kwForm->createView()
);
return $this->render(':backend:kw.html.twig', $templateData);
}
Any help is highly appreciated.
EDIT: Using Symfony 3.1
It's exactly what Alsatian said in the comment. Browser is trying to repeat last request.
However I think that instead of destroying this form you can simply redirect to the same route with $this->redirectToRoute once you processed data, of course if it's not a problem.
Also I see you check at least twice if method is post. If it's not colliding with the rest of your application logic you can specify #Method("POST") in annotation so you don't have to check it directly in code anymore.
Best Regards,
R.

Hide the ID in the URL

In Grails the URL like this
http://localhost:8080/MyApp/show/2
is there a way to hide or to encrypt the id part
/2
i need to do this to prevent users to access others data , for instance my ID is 3 , i could access other user's data by typing
/show/4
You can encode the url. If you replace the 2 with %32, the browser will still interpret it as the character 2. Here is a complete list of characters.
You can send POST request instead of GET - this is an easy way of hiding such a request parameters f.e. in server log files.
Or you can play with GRAILS codecs.
I would not hide the ID from the url. Why? because this would only mask the problem.
Consider having a class defined as :
class Post {
String title
String content
User user //you need this to keep track of the posts owner
//You could use your own custom class or the one used in spring security
...
}
If you use Spring Security Core, you would use a fucntion similar to:
def springSecurityService
#Secured(['ROLE_USER'])
def myFunction(Long id){
def postInstance = Post.read(id)
if(postInstance){
if (postInstance.user.id ==(long)springSecurityService.principal.id){
// springSecurityService?.principal?.id retrieves the id of the user in session
//... redirect to details of whatever you need
}else{
//... redirect because it is not the owner of the post
}
}
else{
//... Redirect or something
}
}
If you are using a simple session you would need to have a function like
def myFunction(Long id){
def postInstance = Post.read(id)
long userId = session["user_id"]
if(postInstance && userId > 0){
if (postInstance.user.id ==userId){
//... redirect to details of whatever you need
}else{
//... redirect because it is not the owner of the post
}
}
else{
//... Redirect or something
}
}
The logic is very similar. Still in my humble opinion you should use the spring Security plugin.

PRG BestPractice Zf2

i have an best practice question.
Its clear what Post/Redirect/Get does, but what will be the bestpractice to handle them?
I think there are 2 methods to handle them.
1.) We call the prg plugin at first on controller action
2.) We first validate the post data, and only redirect to the prg-response if successfull?
My problem about this is, at
1.) We enlarge the response time because of the redirect, this is by default so i think not the best solution
2.) will create an overhead by the every time validation of the form
What did you mean is the better solution aber this case?
regards
UPDATE:
What i mean is, the normal(standard) case is something like this - http://framework.zend.com/manual/2.0/en/modules/zend.mvc.plugins.html#the-post-redirect-get-plugin.
$prg = $this->prg('url');
if ($prg instanceof Response) {
return $prg;
} elseif ($prg === false) {
return new ViewModel(array(...));
}
$form->setData($prg);
This means, that theres after every form submit an redirect executes.
Now, my idea was something like this:
$prg = $this->prg();
$form = $this->getFormLogin();
$data = ($prg instanceof ResponseInterface)
? $this->getRequest()->getPost()
: $prg;
if (false !== $data) {
$form->setData($data);
if (true === $form->isValid()) {
if ($prg instanceOf ResponseInterface) {
return $prg;
}
// Make something within the loginservice or something else
}
The idea behind this was, to only redirect for the PRG only if the form is valid, to save response time and other things (because of bootstrapping settings etc.)
The Zend Framework is designed based on Front-Controller pattern so its essential to redirect the page when you access different resources(controller-action).
moreover when you fire redirect(URL) function from your source code it takes minimal time when you compared the time to access the same(URL) from your browser.
You could reduce the response time to considerable amount when you use classmap_autoloading.
Updated:
for an example i take login process, in the below code i implement both HTTP get and post methods in the same action() but, you can refactor this function based on HTTP methods.
LoginController.php
public function loginAction()
{
//code
if ($request->isPost()) {
//code
if ($isValid) {
return $this->redirect()->toUrl('urUrl');
}
return $this->redirect()->toUrl('urUrl');
}
//code
return $viewModel;
}
After refactoring above code
//it used for HTTP get
public function loginAction()
{
//code
return $viewModel;
}
//it used for HTTP POST
public function loginPostAction()
{
//code
if ($notValid) {
return $this->redirect()->toUrl('urUrl');
}
$viewModel->setTemplate($viewpath);
return $viewModel;
}
You need to modify your routing configuration in such a way to handle for both HTTP get and post methods. if the request is HTTP-get the controller process the loginAction() but if its HTTP-post it process the loginPostAction()
Zend framework 2 - HTTP method Routing
Updated:
The purpose of plugin is to avoid the user to POST the data again to the browser. In your case you are trying to enable the option to POST their data when the form is not valid (you are trying to change the behaviour of PRG plugin). if you really worried about response time don't use PRG plugin. create your custom logic inside your controller-action.
--SJ

How to show a popup on a first page visit? (working with Grails)

When user visits the website first time, popup window has to be shown to user suggesting to register to the newsletter and so on... I imagine that it is done with a cookie detection. What is the proper way of doing that with Grails? We use Spring Security Core plugin, but didn't find how it could help us.
It probably makes sense to use a filter: http://grails.org/doc/latest/guide/theWebLayer.html#filters
If you need to show the popup to all users(not just registered members) then the cookie/session is probably your only solution.
In case that the popup is only displayed to logged in members you might use a filter similar to :
showPopupOnFirstLogin(controller:'*', action:'*') {
before = {
try{
User user = springSecurityService.currentUser
if (user?.mustGetNotification && !request.xhr){
//we ignore ajax requests
redirect(controller:"home", action:"showPopup")
return false
}
}catch (Exception e){
log.error "Failed to redirect", e
}
}
}

Trying to join two independent forms

i'm trying to join two independent forms (login and register) in the
same page.
My idea is (just looking at the signin form):
Create an action that shows both forms (partials):
public function executeLoginAndRegister(sfWebRequest $request){
$this->form_signin = $this->getUser()->getAttribute('form_signin');
}
Each partial calls to its action:
form action="php?> echo url_for('#sf_guard_signin') ?>" method="post">
In the actions i write this code
public function executeSignin($request)
{
//...
$this->form = new $MyFormclass();
if ($this->form->isValid())
{
//...
}else{
// save the form to show the error messages.
$this->getUser()->setAttribute('form_signin', $this->form);
return $this->forward('sfGuardAuth', 'loginAndRegister');
}
}
It works, but, for example, if i execute LoginAndRegister and submit
incorrectly the signin form and I go to another page and then return to
LoginAndRegister, i will find the submiting error messages...
If i execute LoginAndRegister and submit incorrectly the signin form and
open another browser tab, i will find the submiting error messages in
the signin form of the second tab...
Any idea? any better approach?
I would just use sfDoctrineApplyPlugin if i were you :)
I have it, just writing in the if "request->isMethod('post')":
public function executeLoginAndRegister(sfWebRequest $request){
if($request->isMethod('post')){
$this->form_signin = $this->getUser()->getAttribute('form_signin');
}
}
Anyway if my approach has any big error or is not safety i would
thank anyone who tell me.
Javi

Resources