I am trying to validate the form that I have made myself in .twig file.I am not creating form using createFormBuilder. This is my Controller Code that is call for both case 1) for view 2) after submitting the form.
public function cart_newAction(Request $request)
{
$entity = new Product();
$errors = '';
if ($request->getMethod() == 'POST')
{
$validator = $this->get('validator');
$errors = $validator->validate($entity);
if (count($errors) > 0) {
echo 'Error';
}
else {
echo 'Success';
}
}
return $this->render('CartCartBundle:Cart:Add.html.twig', array('errors' => $errors ));
}
this is view file and I am showing errors like this
Add.html.twig
{% for error in errors %}
{{error}}
{% endfor %}
I have set the error in validation.yml file for name that cannot be blank.
So now when I run the view page it every times show the error after I submit the form.
If no error it should not display me the error just show the blank error.
Note:Is there any better way that I can do this so please share it.Remember that I am doing it without createFormBuilder
UPDATE
It always show me Error.Even if my form is valid and don't missing any field.
If you want to make the form yourself then you can't validate it using the Syfmony form validator. You need to use a simple PHP validation Server-side. Something like this
if ($request->getMethod() == 'POST')
{
$username = $_POST['username'];
if ($username == '')
{
// set error message here
}
}
Ok let me be clear. I gonna give you tow solutions, the first is the best and the most proper way:
1) Generate your EntityForm Type: bin/console make:form or d:g:form command.
2) Then just add some few lines to submit and get the errors.
public function cart_newAction(Request $request)
{
$entity = new Product();
$form = $this->createForm(EntityType::class, $entity);
$form->submitForm($request->request->all(), false);
if ($request->getMethod()->isPost())
{
if ($form->isValid()) {
echo 'Error';
}
else {
echo 'Success';
}
}
return $this->render('CartCartBundle:Cart:Add.html.twig', [
'errors' => $form->getErrors(),
]);
}
The second solution is bind your data into your entity object because we need to set the data into our object.
1) First step create a private fonction in your current class to bind all the submited data:
private function bindEntityValues(Product $entity, array $data) {
foreach ($data as $key => $value){
$funcName = 'set'+ucwords($key);
if(method_exists($entity, $funcName)) $entity->$funcName($value);
}
}
Then your cart_newAction should be like this:
public function cart_newAction(Request $request)
{
$entity = new Product();
$this->bindEntityValues(entity, $request->request->all());
$errors= $this->get('validator')->validate($entity)
if (count($errors) > 0) {
echo 'Error';
}
else {
echo 'Success';
}
}
return $this->render('CartCartBundle:Cart:Add.html.twig', ['errors' => $errors]);
}
Wish this helped you to have a clear vision.
You must check if $errors is empty or not :
if (count($errors) > 0) {
return $this->render('CartCartBundle:Cart:Add.html.twig', array('errors' => $errors ));
} else {
return $this->render('CartCartBundle:Cart:Add.html.twig');
}
See the doc here.
Related
I'm turning again on you guys, because I spend my fair share of hours on this "task" and I still can't figure out how to test my service method, without my function connection on database (I have to mock repository functions)
This is my service function
public function getInfo($history, $name)
{
$requestRepository = $this->em->getRepository(Request::class);
if ($history) {
$requests = [];
foreach ($requestRepository->getRequestsByName($name) as $request) {
$requests[] = $requestRepository->transform($request);
}
return $requests;
} else {
$request = $requestRepository->getCompletedRequestByName($name);
if (!is_null($request)) {
return $requestRepository->transform($request);
} else {
return null;
}
}
}
And this is my test
public function testGetInfo()
{
/* This returns errors, because it tries to connect to DATABASE, but I don't wan't that, that's why I figure out I need to mock this
$requestManager = new RequestManager($this->entityManager);
$test = $requestManager->getInfo('histroy', 'antrax.com');
*/
$requestManager = $this->getMockBuilder(RequestManager::class)->disableOriginalConstructor()->setMethods(['getInfo'])
->getMock();
// And rest of this are just my FAILED attempts to figure out, how to test my methods
$queryBuilder = $this->getMockBuilder(RequestRepository::class)->disableOriginalConstructor()
->setMethods(['getInfo'])->getMock();
$test = $queryBuilder->method('getInfo')->willReturnSelf();
$queryBuilder->method('getInfo')->willReturnCallback(function ($field, $value) use ($queryBuilder, $test){
if ($field == 'newStatus') {
$this->assertSame('EXPIRED', $value);
}
return $queryBuilder;
});
}
Can some one please help me how to write a test for my method getInfo so it will have 100% cover. If you need any additional informations, please let me know and I will provide. Thank you!
This is an answer to my problem
public function testGetInfo()
{
$mockEntity = $this->mockEntityManager;
$name = 'antrax.com';
$requestMock = new RequestEntity();
$transformedRequest = [
'id' => 1
];
$requestRepo = $this->getMockBuilder(RequestRepository::class)->disableOriginalConstructor()
->setMethods(['getRequestsByName', 'transform', 'getCompletedRequestByName'])->getMock();
$requestRepo->method('getRequestsByName')->willReturnCallback(function ($passedName) use ($name, $requestMock) {
$this->assertSame($name, $passedName);
return [$requestMock, $requestMock];
});
$requestRepo->method('transform')->willReturnCallback(function ($request) use ($requestMock, $transformedRequest) {
$this->assertSame($requestMock, $request);
return $transformedRequest;
});
$i = 0;
$requestRepo->method('getCompletedRequestByName')->willReturnCallback(function ($passedName) use ($name, $requestMock, &$i) {
$this->assertSame($name, $passedName);
if ($i == 0) {
$i+=1;
return null;
} else {
return $requestMock;
}
});
$mockEntity->method('getRepository')->willReturnCallback(function ($requestClass) use ($requestRepo) {
$this->assertSame(RequestEntity::class, $requestClass);
return $requestRepo;
});
$requestManager = new RequestManager($mockEntity);
$this->assertSame([$transformedRequest, $transformedRequest], $requestManager->getInfo(true, $name));
$this->assertNull($requestManager->getInfo(false, $name));
$this->assertSame($transformedRequest, $requestManager->getInfo(false, $name));
}
i want to create an array as a session table to put it empty in the beggining for my cart shop to display nothing as an empty cart and when i press AddtoCart i want get that array and do an array_push with the new items but i didn't know how to do it
This is the first controller when i create the array empty
public function FrontAction()
{
$pro=new Produit();
$pro->setNom('');
$pro->setQuantite(0);
$pro->setPrix(0);
$em = $this->getDoctrine()->getManager();
$sess=new Session();
$sess->setName('PANIER');
$sess=array('');
array_push($sess,$pro->getNom(),$pro->getQuantite(),$pro->getPrix());
$paniers = $em->getRepository(Panier::class)->findByUserId(1);
$produits = $this->getDoctrine()->getRepository(Produit::class)->findAll();
$boutiques = $this->getDoctrine()->getRepository(Boutique::class)->GetBestShopsDQL();
if ($paniers != null)
{
$prixTotal = 0;
foreach ($paniers as $panier) {
$prixTotal += $panier->getPrixTotal();
}
$resultCount = count($paniers);
return $this->render('BoutiqueBundle:FrontViews:ListBoutique.html.twig', array('produits' => $produits, 'boutiques' => $boutiques,'paniers' => $paniers, 'prixTotal' => $prixTotal,'resultCount' => $resultCount));
}
return $this->render('BoutiqueBundle:FrontViews:ListBoutique.html.twig', array('produits' => $produits, 'boutiques' => $boutiques,'sess'=>$sess));
}
and this is the second controller where i want to fill that empty array with new items
public function ajouterauPanierAction($id)
{
$ses=new Session();
$ses->getName('PANIER');
$test=array('');
$test=$ses;
// $user_id = $this->getUser()->getId(); //à modifier!!!!!
$em = $this->getDoctrine()->getManager();
$produit = $em->getRepository(Produit::class)->find($id);
$test = $em->getRepository(Panier::class)->findExistant($id, 1);
// $session->replace(array_push($produit,));
if(($produit != null)&&(empty($test)))
{
array_push($test,$produit->getNom(),$produit->getQuantite(),$produit->getPrix());
/* $panier = new Panier();
$panier->setProduitId($produit->getId());
$panier->setUserId(1); //à changer avec le fos
$panier->setDate(new \DateTime("now"));
$panier->setPrixTotal($produit->getPrix());
$em->persist($panier);
*/ $em->flush();
$msg = "success";
// return $this->redirectToRoute('Dashboard');
}
else
{
//return $this->render('BoutiqueBundle:FrontViews:404.html.twig');
$msg = "failure";
}
return new JsonResponse(array('msg' => $msg));
}
i didn't know how to do it correctly or if my idea is wrong so hope u guys got what i need to do
Here is how I am doing it in Symfony 4, (I think this part is unchanged). First I have declared my session keys as class constants on the entities to avoid collisions.
class Appointment
{
const SESSION_KEY = 'confirmed_app_entity_appointment';
...
}
Then in the controller use the SessionInterface and it will get autowired into your controller method with a typehinted parameter (SessionInterface $session). Symfony will handle starting the session, just set, get, and/or remove the key as needed.
use Symfony\Component\HttpFoundation\Session\SessionInterface;
...
public function confirmAppointment($first_name, $last_name, $time, SessionInterface $session)
{
...
$session->set(Appointment::SESSION_KEY, $appointment);
$session->set(StaffMember::SESSION_KEY_SELECTED_STAFF, $member);
...
if ($this->isConflict($appointment)) {
$session->remove(Appointment::SESSION_KEY);
$session->remove(StaffMember::SESSION_KEY_AUTH);
$this->addFlash('error', 'Failed to create Appointment, conflict found');
return $this->redirectToRoute('customer');
}
...
}
public function saveAppointment(SessionInterface $session)
{
if (!empty($session->get(Appointment::SESSION_KEY))) {
$appointment = $session->get(Appointment::SESSION_KEY);
}
...
}
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 '
);
}
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?
I have override the existing \yii\db\ActiveRecord with my own class. The method I've override is beforeSave(). I've read the documentation about the usage. But I found it's called twice when checking the record whether it is a new record or not.
This is my code:
class ActiveRecord extends \yii\db\ActiveRecord{
public $count = 0;
public function beforeSave($insert) {
print($this->count++); //i try to investigate it deeper using this "count" property
if(parent::beforeSave($insert)){
if($this->isNewRecord){
print("123"); //this printed out
if($this->hasAttribute('user_create')){
$this->user_create = \Yii::$app->user->identity->id;
}
if($this->hasAttribute('time_create')){
$this->time_create = new \yii\db\Expression('now()');
}
}
else{
print("456"); //and this is also
if($this->hasAttribute('user_upd')){
$this->user_upd = \Yii::$app->user->identity->id;
}
if($this->hasAttribute('time_upd')){
$this->time_upd = new \yii\db\Expression('now()');
}
}
return true;
}else{
return false;
}
}
}
and the output of the code when I do save a new record is as follow
01231456
I made a mistaken in the Controller Side, this is my Code
public function actionCreate() {
$model = new Grup();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
if ($model->save()) {
echo Json::encode(array('status' => 1));
} else {
echo Json::encode(array('status' => 0, 'message' => \kartik\widgets\ActiveForm::validate($model)));
}
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
I shouldn't use $model->save() twice.