How to save multiple value to database using F3 mapper?

199 views
Skip to first unread message

Jago Kapok

unread,
Jan 19, 2017, 2:51:20 AM1/19/17
to f3-fra...@googlegroups.com
Assuming, I have this code :

<form>
 
<input name="field[0]">
 
<input name="field[1]">
 
<input name="field[2]">
</form>

I want to save that value to the same table on one submit.

I have read documentation of F3, but still haven't found a solution. Can anyone help me?

ikkez

unread,
Jan 19, 2017, 3:21:58 AM1/19/17
to f3-fra...@googlegroups.com
Hi. Well usually you would do $mapper->copyfrom('POST'); https://fatfreeframework.com/3.6/sql-mapper#copyfrom
This should work just fine for the Jig and Mongo mapper.

But having an array field in the formular complicates this for the usage with a SQL table, because the mapper cannot store a raw array into a field.
So you need to split this array into multiple fields, or convert it into a json string on write and back to an array on read. Probably with a custom field setter or some load/save events:

in example:

<form>
 
<input name="colors[0]">
 
<input name="colors[1]">
 
<input name="colors[2]">
</form>

ensure that "colors" is a text field in your sql table, or has at least enough capacity to save a json string of all fields.

with events: https://fatfreeframework.com/3.6/cursor#Eventhandlers
// on init or __construct
$encode
= function($self,$pkeys=null) {
 $self
->set('colors',json_encode($self->get('colors')));
};
$decode
= function($self,$pkeys=null) {
 $self
->set('colors',json_decode($self->get('colors'),true));
};
$mapper
->onload($decode);
$mapper
->beforesave($encode);
$mapper
->afterupdate($decode); // only afterupdate here, because a load is initiated by the mapper itself after insert, which then calls the onload decoder

// on post submit in your controller
$mapper
->copyfrom('POST');
$mapper
->save();


// if you load the form data in your controller
$mapper
->load();
$mapper
->copyto('POST'); // if correctly handled in template, the data will show up again in the <input> fields



or with custom setter/getter:
class MyModel extends \DB\Mapper\SQL {

 
function set($key,$val) {
   
if ($key == 'colors') {
      $val
= json_encode($val);
   
}
   
return parent::set($key,$val);
 
}

 
function &get($key) {
    $val
= parent::get($key);
   
if ($key == 'colors') {
      $val
= json_decode($val,true);
   
}
   
return $val;
 
}
}

not tested but it should work somehow like this.

Jago Kapok

unread,
Jan 20, 2017, 3:02:29 AM1/20/17
to f3-fra...@googlegroups.com
Thanks for your answer bro

Maybe this code can be other solution, but I don't khow if it is safe?

public function saveAll() {
  $f3
= \Base::instance();
  $field
= $f3->get('POST.field_name');  // Assuming the name attribute of input field is field_name
       
 
foreach($field as $key => $val){
    $this
->db->exec("INSERT INTO table (field) VALUES ('$val')");
 
}
}

Anatol

unread,
Jan 20, 2017, 2:22:35 PM1/20/17
to Fat-Free Framework
Hey Jago,

but I don't khow if it is safe?

no it´s not. Use parameterized Queries:

cheers,

– anatol
Reply all
Reply to author
Forward
0 new messages