在 Wordpress Advanced Custom Fields PRO 中将行添加到嵌套转发器

Add row to nested repeater in Wordpress Advanced Custom Fields PRO

我是 运行 ACF PRO 5.3.9.2,但我认为这适用于任何带有嵌套中继器的版本。我希望使用 update_field()update_sub_field() 函数将行添加到嵌套转发器(即转发器内的转发器)。

update_field() 函数非常适合一级中继行,即:

update_field( $field_key, $value, $postID );

但我不确定如何将其用于嵌套中继器。这是 ACF 字段结构:

CUSTOM POST TYPE
    Repeater Field - "Media"
         Repeater Field - "Notes"

所以,这是我正在尝试的代码:

$field_key = "field_xxxxxxxxxxxxx"; //NOTES FIELD KEY
$value = get_field($field_key, 12); //GET FIELDS OF POST ID 12, NOTES
$value[] = array("note" => "Here is a new note");
update_field( $field_key, $value, 12 );

但这没有任何作用。无法确定 WHICH "Media" 转发器我希望添加一个 "note" 到。

我可以使用 update_sub_field() 成功 "update" 嵌套转发器字段,就像下面的代码一样,如果嵌套转发器字段中有一行,但它只会覆盖一行并且不能添加到它。如果转发器中当前没有一行,它也将不起作用。

update_sub_field( array('media', 1, 'notes', 2, 'note'), 'Here is a new note!', $postID );

无论是否已有行,我都可以向嵌套转发器添加行?

我能够通过结合 ACF 的功能和常规的好旧 PHP 来实现这一目标。我找不到另一种方法,但我读了其他 posts,人们在其中提到了这种方法,尽管他们没有详细说明或显示代码,所以这是我完成这个的冗长步骤:

  1. 获取你的父转发器的整个数组
  2. 循环直到你点击了你想要编辑的嵌套转发器所在的行
  3. 判断它是否是数组(如果不是,则将其设为数组)
  4. 使用 array_push()
  5. 附加子转发器行
  6. 使用update_field()
  7. 再次保存整个父数组

为了帮助说明 parent/child 关系,请记住我有一个名为 media 的转发器字段和一个名为 notes 的嵌套转发器,它只有 1 个子字段 note。所以如果我使用 get_field('media') 这就是数组 return:

Array
(
    [0] => Array
        (
          [media_title] => 'title 1',
          [notes] => Array
            (
                [0] => Array
                    (
                        [note] => 'HERE IS THE NOTE ADDED'
                    )

                [1] => Array
                    (
                        [note] => 'Here is another note added!'
                    )
            )
    )
    [1] => Array
        (
          [media_title] => 'title 2',
          [notes] => 
    )
 )

所以,在这个例子中,我在父转发器中有 2 个元素,其中一个在嵌套转发器中有 2 个元素,一个在嵌套转发器中没有元素。这很重要,因为您需要先确定嵌套转发器中是否已经建立了一个数组,然后才能添加到它。

//LOOP THROUGH PARENT REPEATER
if( have_rows('media_item', $postID) ): 

    //SET YOUR ROW COUNTER
    $i = 0;

    //MAKE YOUR NEW ARRAY
    $media_item = get_field('media_item', $postID); 

    while( have_rows('media_item', $postID) ) : the_row();          
        if($i == $arrayRowID) { //IF THIS IS THE ROW WE WANT TO EDIT IN PARENT REPEATER                 
            //FIND OUT IF IT IS AN ARRAY ALREADY OR NOT
            if( !is_array($media_item[$i]['notes']) ) {  //WE DONT HAVE ANY NOTES
                $media_item[$i]['notes'] = array();             
            }               
            $addRow = array( //SET YOUR NEW ROW HERE
                'note' => 'This is my new note added!';
            );                  
            //ADD TO ARRAY
            array_push($media_item[$i]['notes'], $addRow);              
        }           
    $i++;
    endwhile;
endif;

因此,我使用 $i 作为计数器来确定我想要的父转发器中的哪一行。如果它是数组中的第二项,$i = 1,因为数组从 0 开始。您还必须在此函数中将您的 post ID 提供给它,但希望它有意义。如果您的父级或子级中继器有很多行,请小心,为了保存它,您必须用刚创建的新中继器覆盖整个父级中继器数组:

$field_key = "field_xxxxxxxxxxxxx" //FIELD KEY OF PARENT REPEATER 'media'
update_field($field_key, $media_item, $postID); 

这将保存新数组,其中包含您附加到子转发器的行。我希望这对某人有所帮助,因为我找不到任何涵盖此方法的示例。我喜欢添加到 ACF 的功能,例如 add_row(),它适用于嵌套中继器!

这是我自己做的,希望对大家有用。

我创建了一个函数,它接受参数并在特定的 post(由 id 获取)中插入一个具有自己字段的转发器,并在该转发器中插入另一个或多个(因为它是转发器)子转发器有自己的领域。

所以如果我有这样的东西:

剧透(中继器)

------------ 名称剧透(输入)

------------剧透标签(输入)

------------ Enlaces (Sub-Repeater)

------------------------ Nombre Enlace(输入)

------------------------ 缠绕(输入)

使用这个函数我可以插入 X "spoiler"s 和 x "Enlaces"s

这里是函数:

function insert_field_subfield($repeater_field, $repeater_subfield, $field_values, $subfield_values, $field_key, $postid){

if(get_field($field_key, $postid)){
    $value = get_field($field_key, $postid);
}else{
    $value = array();
}
$value[] = $field_values;

if(update_field( $field_key, $value, $postid)){

    $i = 0;

    if( have_rows($repeater_field, $postid) ){

        $spoiler_item = get_field($repeater_field, $postid);
        $total_rows = count(get_field($repeater_field, $postid)) -1;

        while( have_rows($repeater_field, $postid) ) : the_row(); 

            if($i == ($total_rows)){

                if( !is_array($spoiler_item[$i][$repeater_subfield]) ) {

                    $spoiler_item[$i][$repeater_subfield] = array();             
                }

                if (count($subfield_values) == count($subfield_values, COUNT_RECURSIVE)){ // subfield_values is not multidimensional

                    array_push($spoiler_item[$i][$repeater_subfield], $subfield_values);

                }else{ // subfield_values is multidimensional

                  foreach($subfield_values as $subfield_value){

                    array_push($spoiler_item[$i][$repeater_subfield], $subfield_value);

                  }

                } 
            }
            $i++;

        endwhile;

    if(update_field($field_key, $spoiler_item, $postid)){
        return true;
    }else{
        return false;
    }

}

}else{
    return false;
}}

致电:

$addField = array("nombre_spoiler" => "Otro nombre", "spoiler_tag" => "Spoiler tag");

对于子中继器内的一个值:

$addSubField = array( 
'nombre_enlace' => 'Valor de un array no multidimensional',
'enlace' => 'Valor enlace');

对于多个值:

$addSubField[] = array( 
'nombre_enlace' => 'multidimensional',
'enlace' => 'Valor enlace');

$addSubField[] = array( 
'nombre_enlace' => '2 multidimensional',
'enlace' => 'Valor enlace 2');

现在电话:

insert_field_subfield('spoiler', 'enlaces', $addField, $addSubField, 'field_586155ce49bf8', 21267);
insert_field_subfield('spoiler', 'enlaces', $addField, $addSubField, 'field_586155ce49bf8', 21267);

我希望这对某些人有用!

P.S。我并不完美,因为我不控制第二个中继器,但这是没有 ACF 的东西 API.

P.S。 field_key是第一个中继器的字段键。

当我有一个嵌套的转发器时,最终对我有用的是使用 add_row 和父字段名称作为前缀。例如,当我在字段 builtdocuments 中嵌套字段 documents 时,我可以使用

$sub_fields = array(
    'current_document'   => "encrypted_file"
);  
  
add_row( 'builtdocuments_document', $sub_fields); 

添加到嵌套转发器成功