Symfony2: Newsletter Subscription - symfony

I need to get the newsletter subscription thing working. The logic i am using is when the user submits his email, i check if there is already a user registered to the site with the email. If yes, i check if he is subscribed to newsletter and do the appropriate subscription. If the email is not in the registered user list, then i have a newsletter table for anonymous users. I check here if he is subscribed or not and do the necessary action.
Here is my controller action code:
/**
* #Route("/newsletter/", name="site_newsletter")
* #return array
*/
public function newsletterSubscriptionAction(httpRequest $request)
{
$email = $request->request->get('email');
try {
$email = $request->request->get('email');
$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery(
'SELECT u FROM MyBundle:User u WHERE u.email = :email'
)->setParameter('email', $email);
$user = $query->getSingleResult();
if(!is_object($user)){ //this means anonymous user not registered to site
$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery(
'SELECT n FROM MyBundle:Newsletter n WHERE n.email = :email AND n.isSubscribed = 1'
)->setParameter('email', $email);
$record = $query->getSingleResult();
if($record){
$msg = "You are already subscribed!";
}else{
$newsletter = new Newsletter();
$newsletter->setEmail($email);
$newsletter->setIsSubscribed(true);
$em = $this->getDoctrine()->getEntityManager();
$em->persist($newsletter);
$em->flush();
$msg = "You have been subscribed to our newsletter! Thank You.";
}
}else{
if($user->getNewsletterSubscription()){
$msg = "You are already subscribed!";
}else{
$user->setNewsletterSubscription(1);
$em = $this->getDoctrine()->getEntityManager();
$em->flush();
$msg = "You have been subscribed to our newsletter! Thank You.";
}
}
}
catch (\Exception $e) {
$msg = 'Some problem occured. Please try again later';
}
if ($this->getRequest()->isXmlHttpRequest()) {
return new \Symfony\Component\HttpFoundation\Response($msg);
return array('msg' => $msg);
}
}
I am using ajax to call this controller action. This isn't working. The data m getting back to the ajax is redirected login page.
I am using FOSUSerBundle by the way to manage users. Is this causing any issue? Whats the best way to implement it?
Thanks in advance!

It sounds like you need to give anon users permission to use your subscription route.
In your security.yml file, add something like:
security:
access_control:
- { path: ^/subscribe, roles: IS_AUTHENTICATED_ANONYMOUSLY }

Related

FOSUserBundle unlock user on login: changes are not persisted

I have locked users that can re-activate their account if they enter a valid ValidationCode on login. As the user is previously locked, I use AuthenticationFailureListener to detect the login failure and determine if there is a valid validation code, according to log tracing every action seems to have correct data and everything should work ok but the problem is the data remains the same, nothing is persisted in database, so no change occurs.
This is my code:
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$userReactivated = false;
// Checks if error is due to user locked and
if ( $exception instanceof LockedException )
{
$username = $request->request->get("_username");
$v_code = $request->request->get("_validation_code");
error_log("{$username} {$v_code}");
$user = $this->em->getRepository("AppUserBundle:Usuario")->findOneBy(array('username' => $username));
if ($user != null)
{
$validationCode = $this->em->getRepository("AppUserBundle:ValidationCode")->findOneBy(array('code' => $v_code));
if ($validationCode != null)
{
error_log("Code " . $validationCode->getId());
if ($validationCode->isActive())
{
$user->setValidationCode($validationCode);
$userReactivated = true;
$user->setLocked(false);
$this->em->persist($user);
$this->em->flush();
}
}
}
}
if (!$userReactivated)
return parent::onAuthenticationFailure($request, $exception);
else
{
return true; // TODO: login user and redirect to home page
}
}
if (!$userReactivated) {
$exception->setUser($user);
return parent::onAuthenticationFailure($request, $exception);
} else {
return true; // TODO: login user and redirect to home page
}

Change password using custom controller - FOSUserBundle (without FormBuilder)

I am implementing my own profile settings page. This will allow the user to change their name, email, password etc.
I understand FOSUserBundle has prebuilt /profile/edit and /profile/change-password. I would like to use the same functionality here except in my own twig bundles. I am not using FormBuilder.
This is my controller for changing user settings.
public function applySettings(Request $request)
{
$user = $this->getUser();
$dm = $this->get('doctrine_mongodb')->getManager();
$repository = $dm->getRepository('AppBundle:User');
$name = $request->get('_username');
$email = $request->get('_email');
$password = $request->get('_password');
$confirm = $request->get('_confirm');
if ($name != null) {
if ($name == ($repository->findOneBy(array('username' => $name )))) {
throw $this->createNotFoundException('Username already in use');
} else {
// username changed
$user->setUsername($name);
}
}
if ($email != null) {
if ($email == ($repository->findOneBy(array('email' => $email )))) {
throw $this->createNotFoundException('Email already in use');
} else {
// email changed
$user->setEmail($email);
}
}
if (strcmp($password, $confirm) == 0) {
// password = confirm here
// change password functionality done here
} else {
throw $this->createNotFoundException(
'Passwords do not match '
);
}
$dm->flush();
return $this->redirectToRoute('settings');
}
Is there a way I can do password validation in my own controller, salt and store the password if valid?
Also is there a way to apply the same validation methods that exist in /register/ and /profile/change-password where the alert comes up if the passwords do not match before submitting?
Any help would be greatly appreciated.
I am using Symfony 2.6.1 and the latest version of FOSUserBundle.
This is the function I used. Works but doesn't do the live validation check.
if (strcmp($password, $confirm) == 0) {
$encoder_service = $this->get('security.encoder_factory');
$encoder = $encoder_service->getEncoder($user);
$newpass = $encoder->encodePassword($password, $user->getSalt());
$user->setPassword($newpass);
} else {
throw $this->createNotFoundException(
'Passwords do not match '
);
}

Symfony - Setting Cookie onKernelRequest

i want to be able to set a Cookie onKernelRequest Method, but the cookie is not beeing set,
Everything else is working fine, what am missing here?
What i want to achieve is that if the user is not logged in and doesnt have the cookie he should see the http basic auth headers.
If the user is logged in or does have the cookie he has access to the preview domains without having to enter their user credentials in http basic auth.
const AUTH_USER = 'myuser';
const AUTH_PW = 'mypass';
public function sendAuthorizationHeader()
{
header('WWW-Authenticate: Basic realm="Preview Domain"');
header('HTTP/1.0 401 Unauthorized');
die();
}
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
$request = $event->getRequest();
$host = $request->getHost();
$loginSuccessful = false;
// check if we are on a preview domain
if (preg_match('/^preview-\d+/', $host)) {
$user = $request->getUser();
$cookie = $request->cookies->get('preview_user');
$phpAuthUser = $request->server->get('PHP_AUTH_USER');
$phpAuthPw = $request->server->get('PHP_AUTH_PW');
if (isset($phpAuthUser) && isset($phpAuthPw)) {
if ($phpAuthUser == self::AUTH_USER && $phpAuthPw == self::AUTH_PW) {
$loginSuccessful = true;
}
} else if ($user === null && $cookie === null) {
$this->sendAuthorizationHeader();
}
if (!$loginSuccessful) {
$this->sendAuthorizationHeader();
} else {
$cookie = new Cookie('preview_user', true, 86400, '/', null, false, false);
$response = new Response();
$response->headers->setCookie($cookie);
$response->sendHeaders();
}
}
}
Setting a cookie on a response object doesn't do anything but adding a cookie to that request. You need to return the same response object, so Symfony renders it back to the client. Rendering it yourself is not a good idea, as there might be contents send later and it's not really testable.
It's easier done in a kernel.response event listener, since you already have a response there. Remember to use the response that your application creates. Do not create it yourself.
If you set the cookie based on logic that should also be available during the request, you can split it into two event listener methods. One will set a request attribute on kernel.request, and the other one will set the cookie on the response on kernel.response:
public function onKernelRequest(GetResponseEvent $event)
{
// your logic goes here. calculate the $result
// ...
$event->getRequest()->attributes->set('my_result', $result);
}
public function onKernelResponse(FilterResponseEvent $event)
{
$response = $event->getResponse();
$request = $event->getRequest();
$myResult = $request->attributes->get('my_result');
$cookie = new Cookie(/* ... */);
$response->headers->setCookie($cookie);
}

symfony2 form without error is not valid

I have the following code in my controller extending BaseController, and that seems not to be working, but I am not able to see a decent error :
$responseFormatter = $this->getResponseFormatter();
$entity = new POI();
$form = $this->createForm(new POIType(), $entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $responseFormatter->successfullResponseFormat($entity)->getResponse();
}
$errors = $this->formErrorFormatter($form);
return $responseFormatter->badResponseFormat('entity.error', $errors)->getResponse();
I even tried the solution of $form->getErrors(true); , and it is empty on my return, so this post ( Symfony2 invalid form without errors ) haven't solved my issue.
Thanks
These may also be one of the causes of not being valid.
First: Not valid a METHOD
Inside `HttpFoundationRequestHandler
$name = $form->getName();
$method = $form->getConfig()->getMethod();
if ($method !== $request->getMethod()) {
return;
}
Form Submitted status is false
This makes your form not submitted. If the form's status is not submitted it will not be valid as well. Not only errors make your form invalid. Following code demonstrates it.
Inside isValid function
public function isValid()
{
if (!$this->submitted) {
return false;
}
if ($this->isDisabled()) {
return true;
}
if (count($this->getErrors(true)) > 0) {
return false;
}
return true;
}
Please try this one
$responseFormatter = $this->getResponseFormatter();
$entity = new POI();
$form = $this->createForm(new POIType(), $entity);
$form->handleRequest($request);
$form->isValid();
$form->getErrorsAsString();
exit;
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $responseFormatter->successfullResponseFormat($entity)->getResponse();
}
$errors = $this->formErrorFormatter($form);
return $responseFormatter->badResponseFormat('entity.error', $errors)->getResponse();
I hope getErrorsAsString() function show error if any error message are occurred during validate.
Or have you forget the following in your template?
{{ form_start(form) }}
If not, how have you render your form?

Symfony login application - sample data doesn't add to the Database

I am new to symfony. I am working on a sample login,signup application using a video tutorial in the link https://www.youtube.com/channel/UCsvlmJMhAkNcbN9FU-5n8Pw
I have followed the same code structure.here is my controller code
public function signupAction(Request $request) {
if ($request->getMethod() == "POST") {
$userName = $request->get('username');
$firstName = $request->get('firstname');
$password = $request->get('password');
$user = new Users();
$user = setUserName($userName);
$user = setFirstName($firstName);
$user = setPassword($password);
$em = $this->getDoctrine()->getEntityManager();
$em->persist($user);
$em->flush();
}
return $this->render('LoginLoginBundle:Default:signup.html.twig');
}
I have created a database named users and a table named users. have inserted one data with user_name,first_name,password.
With the above could it works fine in the video tutorial. but in my application when i click create account button it shows a blank page.Could someone help me out
Try this :)
$user = new Users();
$user->setUserName($userName);
$user->setFirstName($firstName);
$user->setPassword($password);
So, the syntax is not OBJECT = METHOD but rather OBJECT->METHOD ;)

Resources