logo
Ask your Symfony questions! Pay money and get answers fast! (more info)

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.

$5
Remove Blank Object from embed form if not filled out

So I have read http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms so please do not just post a link there.

I can ignore a blank object of another type in my embed form, but I have an interesting use case here I think.

I have a situation where I have a "contact" object (an individual), which may or may not be associated with an "account" (a company). An account has 1:n contacts, a contact has 0:1 accounts.

schema.yml
Account:
columns:
id: { type: integer(4), primary: true, autoincrement: true }
name: { type: string(75), notnull:true }
Contact:
columns:
id: { type: integer(4), primary: true, autoincrement: true }
account_id: { type: integer(4) }
first_name: { type: string(50), notnull: true}
relations:
Account: { local: account_id, foreign: id, foreignAlias: Contacts }


lib/form/doctrine/ContactAdvancedForm.class.php
<?php
class ContactAdvancedForm extends BaseContactForm
{
public function configure()
{
$account = new Account();
$this->getObject()->setAccount($account);
$accountForm = new AccountForm($account);
$this->embedForm('account', $accountForm);
$this->useFields(array('first_name', 'account'));

}
public function saveEmbeddedForms($con = null, $forms = null)
{
if (null === $forms)
{
$account = $this->getValue('account');
$forms = $this->embeddedForms;
if(!isset($account['name']) || strlen($account['name']==0))
{
unset($forms['account']);
}
}

return parent::saveEmbeddedForms($con, $forms);
}


I think this line is the problem
$this->getObject()->setAccount($account);


But I don't know how to unset it, and it's needed to associate the contact with the account in the event an account is created...

No matter what I do, a blank account is still created. Can you offer advice on how to not create a blank account object if the name is not filled out?

This question has been answered.

bmv82 | 10/22/10 at 4:54pm Edit


The experts have suggested, on average, a prize of $5 for this question.

(3) Responses

See a threaded view of answers?

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

  • avatar
    Last edited:
    10/22/10
    5:33pm
    saki says:

    Hi there.

    You have to create a Post Validator:
    http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms
    Read the Creating a Custom Validator part.

    As you can see, the example checks the caption and filename fields and gives error if one of them is missing. If both of them are missing, it removes the empty values. That's you need.

    In your case:

    // no name, remove the empty values
    if (!$value['name'])
    {
    unset($values[$key]);
    }


    I hope this helps... Don't forget to add the post validator to the embed form...

    ps: you can use the trim() function (in the post validator) to avoid whitespace in the name field

    Previous versions of this answer: 10/22/10 at 5:33pm

  • avatar
    Last edited:
    10/26/10
    11:21am
    Gergely Szilagyi says:

    Hi!

    First of all, the best way to avoid these problems, write less code.
    I will post a full-worked and tested solution for this question, tested in sf1.4 with doctrine.

    schema.yml :
    doctrine is very smart, auto-detect relations ( default one-many, like you need in these
    case, and give auto-increment primary key, named "id"


    Account:
    columns:
    name: { type: string(75), notnull: true}


    Contact:
    columns:
    account_id: integer
    first_name: { type: string(50), notnull: true}
    relations:
    Account: { foreignAlias: Contacts }



    Then the CommentForm in lib/form/doctrine/CommentForm.class.php only :
    class ContactForm extends BaseContactForm
    {
    public function configure()
    {
    if( $this->isNew() || $this->getObject()->Account->getId() )
    {
    /*
    * If this ContactForm is new OR the exist Contact object own an exist Account,
    * then we need to embed relation.
    */
    $this->embedRelation('Account');
    $this->useFields(array('first_name', 'Account'));

    if($this->isNew())
    {
    /*
    * If it's new, we enable the empty field for Account name,
    * to separate two case later in Model's overrided save action.
    */
    $this->validatorSchema['Account']['name'] ->setOption('required', false );
    }
    }else {
    /*
    * This case we have an existed Contact object, without binded Account in DB.
    */
    $this->useFields(array('first_name'));
    }
    }

    }



    Then the Account in lib/model/doctrine/Account.class.php :

    class Account extends BaseAccount
    {
    /**
    * Need to know :
    * - the (ContactForm)$form->save() call the (Concact)$object->save() , and this will call first the
    * already parametherized (Account)$account modell's save method in background.
    * - what does this mean:
    * When this method return null, then the $contact->account_id catch null too... :)
    */
    public function save(Doctrine_Connection $conn = null)
    {
    $this->setName(trim($this->getName()));
    if($this->getName())
    {
    return parent::save();
    }else {
    return null;
    }
    }
    }



    Sentence : "Write less, do more = symfony" :D

    Have a nice day!

    Previous versions of this answer: 10/22/10 at 10:03pm | 10/22/10 at 10:04pm

  • avatar
    Last edited:
    10/25/10
    2:20pm
    bmv82 says:

    If you'll look in the saveEmbedded forms, I do the unsetting. Please provide an exact code example if there is code beyond what I have posted that is required.


    public function saveEmbeddedForms($con = null, $forms = null)
    {
    if (null === $forms)
    {
    $account = $this->getValue('account');

    $forms = $this->embeddedForms;

    if(!isset($account['name']) || strlen($account['name']==0))
    {
    unset($forms['account']);
    }
    }
    return parent::saveEmbeddedForms($con, $forms);
    }

This question has expired.





Current status of this question: Completed



Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.