Can I do more than one form for the same model class in symfony? - forms

Well, imagine that we have a register form of a class Customer and we only ask three fields (name,surname,email) and after, when this user logged first time we want to complete this information.
First, we have in lib/form/doctrine a file called 'CustomerForm.class.php' wich is generated automatic on command line. In this file we 'setup' only 3 fields and validators and if we wanna use we do something like that:
$this->form = CustomerForm();
Second, we create manual another form named 'CustomerFormStep1.class.php' where we can setup for validate the other fields. But when we do..
$this->form = CustomerFormStep1();
it returns error: Fatal error: Class 'CustomerFormStep1' not found
What is wrong?
Thanks.

Assuming you have the form defined as:
class CustomerFormStep1 extends sfForm
or similar (sfFormDoctrine etc), and named correctly like you say (CustomerFormStep1.class.php) and in lib/form, then Symfony should just pick the definition up fine. Did you clear the cache after creating and placing it in the right place? (symfony cc).

Create the new CustomerFormStep1 class as #richsage instructed. Then, in your actions you can write something like:
public function executeLogin(){
//before login
$this->form = new CustomerForm();
}
public function executeLoggedIn(){
$this->form = new CustomerFormStep1();
//other steps
}

Haven't you read the tutorial? Extending forms is perfectly described in context with reh admin generator and can of course be applied to any case.

Related

Shopware 6 Forms

Newbie question. How to handle Storefront Form Submit in Shopware 6? How to save the data from form to database? I have an entity, form shown in storefront and a controller but i have no idea how to save the data to entity. Thanks in advance.
you would have to be more specific with the description, of what exactly you are trying to achieve.
But in general, if you already have a controller, that receives the data, then you can get them from the request like this:
$data = $request->request->all();
By this, you have all the values from your form saved in an array $data. You have written, that you already have an entity, so from that I assume, that your entity is already mapped to your database table. So the only thing you have to do, is to use the repository to save the data. For thta, you just need to inject it into your class and get a context. The context depends on where you currently are, so for the purpose of the example, I have just created the default context.
It should look like this:
class MyClass
{
protected $myEntityRepository;
public function __construct(
MyEntityRepository $myEntityRepository
)
{
$this->myEntityRepository = $myEntityRepository;
$this->context = \Shopware\Core\Framework\Context::createDefaultContext();
}
public function myMethod ($data)
{
$this->myEntityRepository->upsert($data, $this->context);
}
}
Hope this helps. I have actually written an article on repositories in Shopware 6, so if you want to get some more information and examples, you can check it here: https://shopwarian.com/repositories-in-shopware-6/.

How to customize register and contact forms in PrestaShop?

I need to know how to customize my contact and register forms. How to add new fileds ( and ) and make the information from these fields required or not required.
I need to know which files I must edit for these forms...
I use prestashop 1.4.7.0
This is really two separate questions as there are major differences in how you would handle each case.
Answer 1
For the registration form you can write a module which contains two hook handler functions. These will be:
public function hookCreateAccountForm() {}
public function hookCreateAccount($params) {}
The first function allows you to add additional fields to the registration form (by default these are inserted at the end of the form authentication.tpl, although you could move them all as a single group elsewhere). It should simply return the additional form html you require.
The second function provides you with two parameters to handle the account creation process. This is executed after the standard fields have been validated and the new customer has been created. Unfortunately you cannot do validation on your additional fields using this (you would need to either use javascript or override AuthController to perform your own authentication in the preProcess() member function). In one of my own custom modules for a site I have the following, for example:
public function hookCreateAccount($params)
{
$id_lang = (int)Configuration::get('PS_LANG_DEFAULT');
$customer = $params['newCustomer'];
$address = new Address(Address::getFirstCustomerAddressId((int)$customer->id));
$membership_number = $params['_POST']['membership_number'];
....
....
}
$params['newCustomer'] is a standard Prestashop element in the array and contains the newly created customer object. Your fields will be in the $params['_POST'] array - in my case it was an input field called membership_number.
Answer 2
For the contact form it's a whole lot more complicated I'm afraid. The simplest method for the html is to just hard-code your additional fields in the template file contact-form.tpl.
To actually process the form you will need to create an override for the controller by ceating a file called ContactController.php in /<web-root>/<your-optional-ps-folder>/override/controller containing something like:
<?php
class ContactController extends ContactControllerCore {
function preProcess()
{
if (Tools::isSubmit('submitMessage'))
{
// The form has been submitted so your field validation code goes in here.
// Get the entered values for your fields using Tools::getValue('<field-name>')
// Flag errors by adding a message to $this->errors e.g.
$this->errors[] = Tools::displayError('I haven't even bothered to check!');
}
parent::preProcess();
if (Tools::isSubmit('submitMessage') && is_empty($this->errors))
{
// Success so now perform any addition required actions
// Note that the only indication of success is that $this->errors is empty
}
}
}
Another method would be to just copy the entire preProcess function from controllers\ContactController and just hack away at it until it does what you want....

Get object in i18n form

Inside embedded i18n form i need to get object.
In this example i got ArtistImageTranslation object, but i need ArtistImage.
Can somebody help me, how to get this?
class ArtistImageTranslationForm extends BaseArtistImageTranslationForm
{
public function configure()
{
$this->getObject();
....
}
}
Have you tried the following?
$artistimage = $this->getObject()->getArtistImage();
I spent half of day today on the same problem and looks like I finally found something ;)
First, if you need to access the fields which are in the "Translation" part of the table you can access them directly from the Object contained in the form. Just access the properties without using the getter (I know it's not the nice way but it works). So you can use something like:
$this->getObject()->id;
$this->getObject()->translated_name;
etc.
If you really need the original object you can access it like this:
$this->getObject()->getTable()->getRelation('ArtistImage')
->fetchRelatedFor($this->getObject());
Hope this helps.
Try :
$artistimage = $this->getObject()->artistImage;
or
$artistimage = $this->getObject()->artist_image;

Symfony form gets messy when calling getObject() in form configuration

I have a Strain model that has a belongsTo relationship with a Sample model, i. e. a strain belongs to a sample.
I am configuring a hidden field in the StrainForm configure() method this way:
$defaultId = (int)$this->getObject()->getSample()->getTable()->getDefaultSampleId();
$this->setWidget('sample_id', new sfWidgetFormInputHidden(array('default' => $defaultId)));
Whenever I create a new Strain, the $form->save() fails. The debug toolbar revealed that it tries to save a Sample object first and I do not know why.
However, if I retrieve the default sample ID using the table it works like a charm:
$defaultId = (int)Doctrine_Core::getTable('Sample')->getDefaultSampleId();
$this->setWidget('sample_id', new sfWidgetFormInputHidden(array('default' => $defaultId)));
My question here is what can be happening with the getObject()->getSample()... sequence of methods that causes the StrainForm to think it has to save a Sample object instead of Strain.
I tried to debug with xdebug but I cannot came up with a clear conclusion.
Any thoughts?
Thanks!!
When you call getSample its creating a Sample instance. This is automatically attached to the Strain object, thus when you save you also save the Sample.
An altenrative to calling getSample would be to chain through Strain object to the Sample table since i assume youre only doing this so your not hardcodeing the Sample's name in related form:
// note Sample is the alias not necessarily the Model name
$defaultId = Doctrine_Core::getTable($this->getObject()->getTable()->getRelation('Sample')->getModel())->getDefaultId();
Your solution probably falls over because you can't use getObject() on a new form (as at that stage the object simply doesn't exist).
Edit: Why don't you pass the default Sample in via the options array and then access it from within the form class via $this->getOption('Sample') (if I remember correctly)?

What is correctness in symfony to fill a form in two steps?

Hy,
What is correctness in symfony to fill a form in two steps? Imagine that we have a entity called Enterprise and we want to create a form with only required fields and another form, that when the user login can fill the other non-required fields.
How is the correctness form? Now i have a form to registration ('lib/form/doctrine/EnterpriseForm.class.php') and another ('lib/form/doctrine/EnterpriseCompleteForm.class.php').In every class we set labels, validators, ... but the problem is in the second form. When i try to submit it gives me an error because i have'nt post required fields defined in model. How can i do that? Is that way correct? How can i fix this?
thanks.
You should unset every non needed form field in the second form (of course you should keep a hidden field with the ID of the record).
Basically you just update the record with the second form so every required field in your database already as a value.
It would help if you post the code of the second form.
So in summary your approach is valid (maybe there are better ways I don't know), just make sure that your code is correct.
Edit:
So if I got you correctly then the form you use in your code updates an existing object. You should pass this object to the form knows, that the object already exists and can validate the values accordingly:
public function executeStepOne(sfWebRequest $request){
$this->customer = Doctrine::getTable('Customer')->find(1);
$this->forward404Unless($this->customer);
$this->form = new CustomerFormStepOne($this->customer);
if ($request->isMethod(sfRequest::POST)){
$this->processRegisterForm($request, $this->form,'paso2');
}
For the duplicate key error, check your database definition if the primary key of this table gets incremented automatically.
Well Felix, i do it "unset" changes and it works fine... but i have a problem. I try to do update on the same action. My code looks like that.
in actions
public function executeStepOne(sfWebRequest $request){
$this->form = new CustomerFormStepOne();
if ($request->isMethod(sfRequest::POST)){
$this->processRegisterForm($request, $this->form,'paso2');
}else{
$this->customer = Doctrine::getTable('Customer')-> find(1);
$this->forward404Unless($this->customer);
}
}
where processRegisterForm code is :
protected function processRegisterForm(sfWebRequest $request, sfForm $form,$route)
{
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$customer = $form->save();
$this->redirect('customer/'.$route);
}
}
if i try to do this they returns me an error 'primary key duplicate'.