0

I am trying to save multiple textfield by language, and when saving if there is an empty textfield of any language, ignore it but for some error my code does not work correctly and when i click submit only save the first textfield

Database

+----------+------------+---------------+
| email_id | email_lang | email_content |
+----------+------------+---------------+
|          |            |               |
+----------+------------+---------------+

Html

<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">

   <input type="text" value="<?php echo $_GET['id']; ?>" name="email_id" hidden>

   <?php foreach ($languages as $lang): ?>
   <input type="text" value="<?php echo $lang ?>" name="email_lang">
   <textarea type="text" value="1" name="email_content"></textarea>
   <?php endforeach ?>

<button type="submit" name="save">Save</button>
</form>

Php

<?php

if ($_SERVER['REQUEST_METHOD'] == 'POST'){

$sentence = $connect->prepare("INSERT INTO emailtemplates (email_id,email_lang,email_content) VALUES (:email_id, :email_lang, :email_content)");

$email_id = $_POST['email_id'];
$email_lang = $_POST['email_lang'];
$email_content = $_POST['email_content'];

$sentence->execute(array(
        ':email_id' => $email_id,
        ':email_lang' => $email_lang,
        ':email_content' => $email_content
        ));
}

$languages = ['en', 'fr', 'ru'];

require '../views/new.email.view.php';

?>

Expected results

+----------+------------+-----------------+
| email_id | email_lang |  email_content  |
+----------+------------+-----------------+
|        1 | en         | english content |
|        1 | fr         | french content  |
+----------+------------+-----------------+
bytingo
  • 45
  • 4
  • How exactly does the code "not work correctly"? What's the problem? – David Nov 19 '20 at 11:37
  • when I save it to the database it doesn't save – bytingo Nov 19 '20 at 11:38
  • 1
    Do you get any errors? Have you got PDO set to throw errors when SQL problems occur? have you got error logging set up correctly in PHP? If not, set those things up, then re-run your code and check the error log file. "doesn't save" isn't a useful description of your problem - there could be multiple reasons for that. Enable error logging, and then do also some proper debugging work, please. We can't run your code to debug it, only you can do that. You should check that all the POST values are populated as you expect before executing the query, for example. – ADyson Nov 19 '20 at 11:42
  • 1
    P.S. a more general point about HTML forms - for hidden values, instead of using a text field and marking it `hidden` you can use an actual ` – ADyson Nov 19 '20 at 11:44
  • the problem is in php logic...when i click submit only save the first textfield – bytingo Nov 19 '20 at 12:11
  • 1
    Unfortunately the answer is delayed, so here is what you can do: name your inputs like ` – Your Common Sense Nov 20 '20 at 13:15

1 Answers1

2

HTML part

Your input fields in the HTML form need to have names which will allow you to identify the language. In HTML you can create field names with square brackets. When PHP receives these values it will treat them as an array. You can define a <textarea> like this:

<textarea name="email_content[fr]">

Then in PHP you can access the value using the following syntax:

$french = $_POST['email_content']['fr'];

Notes:

  • HTML <textarea> doesn't have type nor value attributes.
  • Instead of adding hidden attribute to the <input> elements, just specify the type="hidden".
  • When outputting any dynamic content within HTML you should take care of XSS protection.
  • Instead of <?php echo $var ?> you can use the shorter syntax <?=$var ?>

Your complete HTML form might then look something like this:

<form action="<?=htmlspecialchars($_SERVER['PHP_SELF'])?>" method="post">
    <input type="hidden" value="<?=$id?>" name="email_id">

    <?php foreach ($languages as $lang) : ?>
        <textarea value="1" name="email_content[<?=htmlspecialchars($lang)?>]" placeholder="<?=htmlspecialchars($lang)?>" value="<?=htmlspecialchars($lang)?>"></textarea>
    <?php endforeach ?>

    <button type="submit" name="save">Save</button>
</form>

Once the form is received in PHP your $_POST should contain something like this:

array (
  'email_id' => '12',
  'email_content' => 
  array (
    'en' => '',
    'fr' => 'French text',
    'ru' => '',
  ),
  'save' => '',
)

PHP part

To save multiple values in PHP using PDO you need to use a loop. Before the loop, you should prepare the statement and bind parameters. PDO_stmt::bind_param() is rarely used, but in this situation it can make your code cleaner. You should also perform all inserts inside of a transaction.

$pdo->beginTransaction();

$stmt = $pdo->prepare("INSERT INTO emailtemplates (email_id,email_lang,email_content) 
                        VALUES (:email_id, :email_lang, :email_content)");
$stmt->bindParam('email_id', $_POST['email_id']);
$stmt->bindParam('email_lang', $lang);
$stmt->bindParam('email_content', $contents);

foreach ($_POST['email_content'] as $lang => $contents) {
    if ($contents && in_array($lang, $languages, true)) {
        $stmt->execute();
    }
}

$pdo->commit();

If you wish to use the simpler syntax you can use PDO_stmt::execute() to pass the parameters without prior binding.

$pdo->beginTransaction();

$stmt = $pdo->prepare("INSERT INTO emailtemplates (email_id,email_lang,email_content) 
                        VALUES (:email_id, :email_lang, :email_content)");

foreach ($_POST['email_content'] as $lang => $contents) {
    if ($contents && in_array($lang, $languages, true)) {
        $stmt->execute([
            'email_id' => $_POST['email_id'],
            'email_lang' => $lang,
            'email_content' => $contents,
        ]);
    }
}

$pdo->commit();

The following line checks if contents were provided and language is in the array of languages you specified.

if ($contents && in_array($lang, $languages, true)) {
Dharman
  • 30,962
  • 25
  • 85
  • 135