将发布的多个数组转换为codeigniter的insert_batch样式

时间:2012-02-15 13:22:59

标签: arrays forms codeigniter batch-file multilingual

我正在尝试使用Codeigniter创建多语言表单。

我有一个POST数组:

Array
(
  [title] => Array
    (
        [en] => English Title
        [de] => German Title
    )

  [url] => Array
    (
        [en] => English URL
        [de] => German URL
    )
)

我想将其转换为codeigniter insert_batch('tablename',$data)格式,如:

Array
(
  [0] => Array
    (
        [lang] => en
        [title] => English Title
        [url] => English URL
    )

  [1] => Array
    (
       [lang] => de  // Assuming user didn't fill `_de` labeled input fields.
       [title] => 
       [url] =>
    )
) 

将数据存储在db中:

|id|lang|    title      |    url      |
|--|----|---------------|-------------|
|  | en | English Title | English URL |
---------------------------------------

我怎样才能做到这一点?我需要将post数组转换为insert_batch的数据数组样式。在上方,array[1]仅包含预定义的lang de。所以array[1]对我来说是空的。所以我还需要从最终$data中删除空数组。

下面,您将找到视图文件。

<div id="tabs">
  <?php echo form_open('controller/post_target',array('name'=>'add_page')); ?>
  <ul>
    <?php foreach($lang_data as $r):?>
    <li><a href="#tab_<?=$r->lang;?>"><?=$r->name;?></a></li>
    <?php endforeach; ?>        
  </ul>

  <?php foreach($query_lang as $r):?>
  <div id="tab_<?=$r->lang;?>">
    <?php echo form_label('Page Title','title'); ?>
    <?php 
      $attr1 = array('name' => 'title[' . $r->lang . ']');
      echo form_input($attr1); 

      $attr2 = array(name' => 'url[' . $r->lang . ']');
      echo form_input($attr2); 
    ?>
  </div>
  <?php endforeach; ?>
    <?php echo form_submit('submit','Save'); ?>
  <?php echo form_close(); ?>
</div>

仅仅是为了获取信息,我划了几行作为控制器,但我希望有一个干净编码的控制器。如果数组为空,我的版本也无法检查它。 :(欢迎任何建议更专业的方式。

if($this->input->post('submit'))
{
  $data = $this->input->post();
  unset($data['submit']); // SELF NOTE : IT should be easier way to do this   

  foreach ($data as $key => $value)
  {
    $counter = 0;
    foreach ($value as $key_inner => $value_inner)
    {
      if( ! isset($db_array[$counter])) $db_array[$counter] = array();
      //Above line enable us to use '+=' operand below in foreach loop

      $db_array[$counter] += array(
          'lang' => $key_inner,
          $key => $value_inner
      );          
      $counter ++;
    }
  }

  //echo '<pre>'; print_r($db_array); echo '</pre>' . '<br />';

  if($this->db->insert_batch('test',$db_array)) echo 'record saved';
}

2 个答案:

答案 0 :(得分:0)

你可以创建一些功能来做到这一点。由于lang属性具有特殊行为(与title或url不同),我认为最好在数组中定义语言。

我在下面创建了两个函数,第一个函数将输入数据转换为批量插入所需的格式,第二个函数删除空行(lang应该被忽略,因为它总是被设置)。

我建议您手动设置$ data以使用要翻译的字段,而不是传递整个$_POST值。您可能会在将来添加其他未翻译的输入,我会建议使用所有输入而不是黑名单的白名单机制(取消设置提交按钮)。

UPDATE 将$ fields参数添加为已翻译的字段列表

$data = prepare_data_for_insert($data, array('title', 'url'), array('en', 'de'));
var_dump($data);
$data = remove_empty_rows($data, array('lang'));
var_dump($data);

function prepare_data_for_insert($data, $fields, $langs) {
    $result = array();

    $i = 0;
    // foreach language defined
    foreach ($langs as $lang) {
        // set the languge
        $result[$i]['lang'] = $lang;
        // foreach field that we want to translate
        foreach ($fields as $field) {
            // set the value for the current language
            $result[$i][$field] = $data[$field][$lang];
        }
        $i++;
    }

    return $result;
}

function remove_empty_rows($data, $ignore_fields = array()) {
    $result = array();

    // result
    foreach ($data as $item) {
        $has_values = false;
        foreach ($item as $key => $value) {
            // check if the key is ignored
            if (in_array($key, $ignore_fields)) {
                continue;
            }

            // if a value was set
            if ($value != '') {
                // the array has values
                $has_values = true;
                // don't search for other values
                break;
            }
        }

        // if the array has values
        if ($has_values) {
            // save the row in the result
            $result[] = $item;
        }
    }

    return $result;
}

答案 1 :(得分:0)

我想,你可以这样做:

$langs = array_keys($post["title"]);
$batch = array();
foreach ($langs as $lang) {
      $tmp = array();
      $tmp["title"] = $post["title"][$lang];
      $tmp["url"] = $post["url"][$lang];
      $batch[] = $tmp;
}

未经测试且未检查后期结构中的任何错误。