Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert all text fields individually along with the first text field value [many to one relationship]

Tags:

php

symfony

1. Intro

I'm wondering if there is a way to save a set of text fields each one in a new row in the database and in each one the value of the first box will also be saved along with it.

2. Explanation

Here is the form:

enter image description here

When the user hits save it should be saved in the database as:

enter image description here

My table structure is

enter image description here

3. What I'm doing right now ?!

3.1 - In my addNew.php (the from class file (I know I'm not following the naming convention, my bad) in the constructor I get a list of languages from my controller (addNewAction()).

I loop through the array of languages and generate the text fields for the language translation.

3.2- When the user clicks save I loop through the text fields and check for the language key text field and save it's value in a variable and use that variable each time when I loop through the translation text fields

4. My current code


4.1 - addNewAction

public function addNewAction()
{
  // to add new key and translation associated with it
  // an array of optnions which cotains list of languages

  $options = $this->getAllLanguages();
  $form = $this->createForm(new AddNew($options));
  $form->bind($this->getRequest());

  if ($form->isValid()) {
      foreach($form->getData() as $key => $value){
        $oTranslation = new Translations();
        if($key == 'languageKey'){
          $languageKey = $value;
          continue;
        }

        $locale = $key;
        $translation = $value;
        $language = $this->getDoctrine()
                    ->getRepository('CodeizSDBTranslatorBundle:Languages');
        $query = $language->createQueryBuilder('l')
                           ->select('l.id')
                           ->where('l.locale = :locale')
                           ->setParameter('locale' , $locale)
                           ->getQuery();
        $id = $query->getResult();
        $oTranslation->setLanguageId($id[0]['id']);
                     $oTranslation->setLanguageKey($languageKey);
                     $oTranslation->setTranslation($translation);
                  $em = $this->getDoctrine()->getManager();
      $em->persist($oTranslation);
      $em->flush();
    }



      return $this->redirect($this->generateUrl('codeiz_sdb_translator_addlanguagekey'));
  }
   return $this->render('CodeizSDBTranslatorBundle:Default:addNewKey.html.twig', array(
        'form' => $form->createView(),
    ));
}

4.2 - addNew.php (from class)

<?php
namespace Codeiz\SDBTranslatorBundle\Form\Add;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class AddNew extends AbstractType
{
    private $languages;
    public function __construct($languages){
        $this->languages = $languages;
    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->add('languageKey');
        foreach ($this->languages as $key => $value) {
                    $builder->add($value['locale'] , 'text' , array('label'=>$value['description']) );
        }


    }

    public function getName()
    {
        return 'addnew';
    }
}

4.3 - Here is what the array I'm passing to the form to generate the text fields, which is stored in $this->languages, looks like

Array
(
    [0] => Array
        (
            [id] => 1
            [locale] => en_US
            [description] => English - United States
        )

    [1] => Array
        (
            [id] => 2
            [locale] => fr_FR
            [description] => Frenish
        )

)

5. Possible solutions

These are things I just thought I might do as a work around:

5.1- use my code BLAH .

5.2- restructure the database to be each language is a column .

6. Conclusion

I have tried so many things that didn't work out for me, and the way I'm doing it right now makes it look immature.

Aside from all that, I'm still learning and I really want to solve this problem as-is without restructuring the database and such.

note:

please avoid discussing performance , keep your focus on the problem ... and please change the title as im sure this isnt the right way to describe the problem .. or even better suggest one .. and if you fiend some incorrect technical terms please edit them .. thanks :)

like image 405
Hussein Nazzal Avatar asked Feb 26 '13 16:02

Hussein Nazzal


Video Answer


2 Answers

The below code has a form similar to yours, and writes out SQL select/insert statements for each of the translations. NOTE, the SELECT needs to pass the ID into the second query (the part that says languageid in the values) since you need to get the ID from the database based off the name of the language.

<?php
echo '<form method="post">
<input type="text" name="LanguageKey" value="_hello"/>
<input type="text" name="EnglishUS" value="sup"/>
<input type="text" name="French" value="bon"/>
<input type="submit" value="Submit"/>
</form>';

print_r($_POST);
echo "<br />\n";

        foreach ($_POST as $key => $val)
        {
                if ($key != 'LanguageKey')
                {
                        echo $key.': '.$val."<br />\n";
                        echo "SELECT id FROM Languages where description = '$key'<br />\n";
                        echo 'INSERT INTO translation (LanguageId,LanguageKey,Translation) VALUES (\'languageid\',\''.$_POST['LanguageKey'].'\',\''.$val.'\')'."<br />\n";
                }
        }
?>

Results:

snip of page when it's run

like image 200
uNople Avatar answered Oct 23 '22 17:10

uNople


What you're looking for in this instance is Embedded Forms.

This allows you to create a Translation Form with Multiple Translations within it.

Add your language key field to the parent form, and then you can loop through the child translations in the POST data.

This is a more elegant and extensible solution, but if it ain't broke don't fix it.

like image 22
james_t Avatar answered Oct 23 '22 19:10

james_t