ACF programmatically add repeater - wordpress

I'm using Advanced Custom Fields (ACF) and trying to add a repeater programmatically to an existing group (group_5621b0871e1b1), but it doesn't work. The same code works for a text field but not for the repeater.
In my plugin:
add_action( 'acf/init', 'acf_add_field_royalties' );
function acf_add_field_royalties() {
if ( function_exists( 'acf_add_local_field_group' ) ) {
acf_add_local_field( array (
'key' => 'field_store_royalties',
'label' => 'Royalties',
'name' => 'store_royalties1',
'type' => 'repeater',
'parent' => 'group_5621b0871e1b1',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => '',
'max' => '',
'layout' => 'table',
'button_label' => 'Add new royalty period',
'sub_fields' => array (
array (
'key' => 'field_start_date',
'label' => 'Start Date',
'name' => 'start_date1',
'type' => 'date_picker',
'instructions' => '',
'required' => 1,
'display_format' => 'F j, Y',
'return_format' => 'd/m/Y',
'first_day' => 1,
),
array (
'key' => 'field_end_date',
'label' => 'End date',
'name' => 'end_date1',
'type' => 'date_picker',
'instructions' => '',
'display_format' => 'F j, Y',
'return_format' => 'd/m/Y',
'first_day' => 1,
),
array (
'key' => 'field_royalty_rate',
'label' => 'Royalty Rate',
'name' => 'royalty_rate1',
'type' => 'number',
'instructions' => '',
'required' => 1,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => 0,
'placeholder' => '',
'prepend' => '',
'append' => '%',
'min' => 0,
'max' => 100,
'step' => 1,
'readonly' => 0,
'disabled' => 0,
)
)
));
}
}
It shows this error in the group_5621b0871e1b1 group:
Warning: Invalid argument supplied for foreach() in /usr/share/nginx/html/wordpress4/wp-content/plugins/advanced-custom-fields-pro/pro/fields/repeater.php on line 255
Warning: Invalid argument supplied for foreach() in /usr/share/nginx/html/wordpress4/wp-content/plugins/advanced-custom-fields-pro/pro/fields/repeater.php on line 320
Am I doing something wrong?
Is it possible to add a repeater programmatically.

Since the repeater field was added using acf_add_local_field, each subfield needs to be added with acf_add_local_field as well.
Delete all of the subfields, including the 'subfields' => array
line, from the repeater field.
Add each subfield in a new acf_add_local_field
When adding subfields, Make sure to add 'parent' => 'repeater_field_key' to the subfields.
Your code would now look like:
add_action( 'acf/init', 'acf_add_field_royalties' );
function acf_add_field_royalties() {
if ( function_exists( 'acf_add_local_field_group' ) ) {
/**
* Initial Repeater Field
*
*/
acf_add_local_field( array (
'key' => 'field_store_royalties',
'label' => 'Royalties',
'name' => 'store_royalties1',
'type' => 'repeater',
'parent' => 'group_5621b0871e1b1',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => '',
'max' => '',
'layout' => 'table',
'button_label' => 'Add new royalty period'
));
/**
* Add Start Date Subfield
*
*/
acf_add_local_field( array (
'key' => 'field_start_date',
'label' => 'Start Date',
'name' => 'start_date1',
'parent' => 'field_store_royalties', // key of parent repeater
'type' => 'date_picker',
'instructions' => '',
'required' => 1,
'display_format' => 'F j, Y',
'return_format' => 'd/m/Y',
'first_day' => 1,
));
/**
* Add End Date Subfield
*
*/
acf_add_local_field( array (
'key' => 'field_end_date',
'label' => 'End date',
'name' => 'end_date1',
'parent' => 'field_store_royalties', // key of parent repeater
'type' => 'date_picker',
'instructions' => '',
'display_format' => 'F j, Y',
'return_format' => 'd/m/Y',
'first_day' => 1,
));
/**
* Add Royalty Rate Subfield
*
*/
acf_add_local_field( array (
'key' => 'field_royalty_rate',
'label' => 'Royalty Rate',
'name' => 'royalty_rate1',
'parent' => 'field_store_royalties', // key of parent repeater
'type' => 'number',
'instructions' => '',
'required' => 1,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => 0,
'placeholder' => '',
'prepend' => '',
'append' => '%',
'min' => 0,
'max' => 100,
'step' => 1,
'readonly' => 0,
'disabled' => 0,
));
}
}

Related

Wordpress - Trying to display date from custom form two different ways

I am trying to create an events page in Wordpress. I am using the Advanced Custom Fields plugin to generate my forms. I would like to style the month and year differently from the day in the listing section. However, I don't want to make the user have to input the same date twice in the back-end just for this. Is there a way to display the content from the one form in two different calibrations on the front-end? For example, can I display it once as month and year then once again as just the day? Is there any other workaround? Any advice would be appreciated.
Here is my custom form code:
if( function_exists('acf_add_local_field_group') ):
acf_add_local_field_group(array(
'key' => 'group_5fec83c0a2f7b',
'title' => 'Event Particulars',
'fields' => array(
array(
'key' => 'field_5fec83ca0dc8b',
'label' => 'Date of event',
'name' => 'date_of_event',
'type' => 'date_picker',
'instructions' => '',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5fec84a00dc8c',
'operator' => '!=empty',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'display_format' => 'Y F j',
'return_format' => 'Y F j',
'first_day' => 1,
),
array(
'key' => 'field_5fec84a00dc8c',
'label' => '',
'name' => '',
'type' => 'text',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => '',
'placeholder' => '',
'prepend' => '',
'append' => '',
'maxlength' => '',
),
),
'location' => array(
array(
array(
'param' => 'page_type',
'operator' => '==',
'value' => 'front_page',
),
),
),
'menu_order' => 0,
'position' => 'normal',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
'active' => true,
'description' => '',
));
endif;
You can load the value of the date field, create a date object and then format that date object as you prefer:
// Load field value.
$date_string = get_field('date_of_event');
// Create DateTime object from value.
// Here you must use the format that you specified as the "return format" of the date field in ACF.
$date = DateTime::createFromFormat('Y F j', $date_string);
// Now you can use the date object to print the date in different formats:
echo $date->format('M Y');
echo $date->format('j M Y');
Have a look at the "Modifiy value" section of the docs:
https://www.advancedcustomfields.com/resources/date-picker/

Wordpress ACF add row to flexible content programmatically

I want to add a row to my posts flexible content field.
I create my ACF fields using the code from the export tool, this is a part of it:
acf_add_local_field_group(array(
'key' => 'group_5c4c39a08349a',
'title' => 'Posts page',
'fields' => array(
array(
'key' => 'field_5c4c39aab1ed4',
'label' => 'Blokken positie',
'name' => 'block_position',
'type' => 'radio',
'instructions' => 'Geef aan waar de pagina blokken geplaatst moeten worden',
'required' => 1,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'choices' => array(
0 => 'Boven de berichten',
1 => 'Onder de berichten',
),
'allow_null' => 0,
'other_choice' => 0,
'default_value' => 1,
'layout' => 'vertical',
'return_format' => 'value',
'save_other_choice' => 0,
),
),
'location' => array(
array(
array(
'param' => 'page_type',
'operator' => '==',
'value' => 'posts_page',
),
),
),
'menu_order' => 6,
'position' => 'normal',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
'active' => true,
'description' => '',
));
acf_add_local_field_group(array(
'key' => 'group_5c4a061a6be68',
'title' => 'Page/ Post blocks',
'fields' => array(
array(
'key' => 'field_5c4a0645c3baa',
'label' => 'Blocks',
'name' => 'blocks',
'type' => 'flexible_content',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'layouts' => array(
'layout_5c4a084c7953b' => array(
'key' => 'layout_5c4a084c7953b',
'name' => 'news_slider',
'label' => 'Nieuws slider',
'display' => 'block',
'sub_fields' => array(
array(
'key' => 'field_5c4a085f7953e',
'label' => 'Type',
'name' => 'type',
'type' => 'select',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'choices' => array(
0 => 'Laatste berichten',
1 => 'Berichten uit een categorie',
2 => 'Zelf de berichten selecteren',
),
'default_value' => array(
),
'allow_null' => 0,
'multiple' => 0,
'ui' => 0,
'return_format' => 'value',
'ajax' => 0,
'placeholder' => '',
),
array(
'key' => 'field_5c4ac2d1986b9',
'label' => 'Aantal nieuws artikelen',
'name' => 'news_items',
'type' => 'number',
'instructions' => '',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5c4a085f7953e',
'operator' => '==',
'value' => '0',
),
),
array(
array(
'field' => 'field_5c4a085f7953e',
'operator' => '==',
'value' => '1',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => 9,
'placeholder' => '',
'prepend' => '',
'append' => '',
'min' => 3,
'max' => 18,
'step' => 3,
),
array(
'key' => 'field_5c4a093b2ba54',
'label' => 'Toon nieuws uit categorie',
'name' => 'news_category',
'type' => 'taxonomy',
'instructions' => '',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5c4a085f7953e',
'operator' => '==',
'value' => '1',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'taxonomy' => 'category',
'field_type' => 'select',
'allow_null' => 0,
'add_term' => 1,
'save_terms' => 0,
'load_terms' => 0,
'return_format' => 'object',
'multiple' => 0,
),
array(
'key' => 'field_5c4a09e7ee82f',
'label' => 'Selecteer nieuws berichten',
'name' => 'news_item_collection',
'type' => 'repeater',
'instructions' => 'De slider laat 3 items per slide zien. Zorg dat het aantal items deelbaar is door 3.',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5c4a085f7953e',
'operator' => '==',
'value' => '2',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => 0,
'max' => 0,
'layout' => 'table',
'button_label' => '',
'sub_fields' => array(
array(
'key' => 'field_5c4a0a08ee830',
'label' => 'Nieuws item',
'name' => 'news_item',
'type' => 'post_object',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'post_type' => array(
0 => 'post',
),
'taxonomy' => '',
'allow_null' => 0,
'multiple' => 0,
'return_format' => 'object',
'ui' => 1,
),
),
),
),
'min' => '',
'max' => '',
),
'layout_5c4a065576f71' => array(
'key' => '5c4a065576f71',
'name' => 'text',
'label' => 'Tekst (1 blok per rij)',
'display' => 'block',
'sub_fields' => array(
array(
'key' => 'field_5c4a0666c3bab',
'label' => 'Tekst',
'name' => 'text_content',
'type' => 'wysiwyg',
'instructions' => 'Het wordt afgeraden om in deze editor afbeeldingen in te voegen. Gebruik bij voorkeur het block "Afbeelding" hiervoor.',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => '',
'tabs' => 'visual',
'toolbar' => 'full',
'media_upload' => 1,
'delay' => 0,
),
),
'min' => '',
'max' => '',
),
When I create or edit a post I can see and use these fields.
Now I have a script to import posts and I want to add the field Tekst (1 blok per rij) as a new row programmatically.
I've tried using add_sub_row and update_field but none worked properly.
When I use add_sub_row like this I always get a return value of false:
add_sub_row([ 'field_5c4a0645c3baa', 1, 'field_5c4a0666c3bab'], [
'field_5c4a0666c3bab' => 'test'
], $post)
When I use update_field I do get a response which makes it look like the field has been added, but I can't see it when I go to wp-admin and open the post:
update_field('field_5c4a0645c3baa', [
'acf_fc_layout' => 'text',
'text_content' => 'test'
], $post)
How should I use these methods? Because I've tried to use the manual of ACF for it but I don't really understand how to put it to use on flexible content.
I've contacted the ACF support.
They told me this:
Thanks for reaching out to us.
Unfortunately, I'm afraid it's not possible to add using the add_row
function with the flexible content field.
However, you could implement a custom solution using the update_field
function to add sub_rows to the flexible content field.
The developer already has it in his todo and probably this option will
be available in future updates.
Apologies for the inconvenience.
Later they replied with this:
Thanks for the follow up.
Ideally, you need to load the field, modify the field values and
update the field using update_field.
Kindly have a look at the following article from the support forums.
https://support.advancedcustomfields.com/forums/topic/issues-with-add_rows-and-flexible-content/
Hope this helps.
The link helped me to create a new row in the flexible content.
Using this code:
$row_i = add_row(
'field_55ce0e107c687',
[
'acf_fc_layout' => 'headline',
'field_55df18296e4b3' => 'headline text'
],
$ID
);
So I had to adjust it to my field names:
add_row(
'field_5c4a0645c3baa', [
'acf_fc_layout' => 'text',
'field_5c4a0666c3bab' => $block[ 'value' ],
], $post);
Now it works fine.

Can't get custom post type id inside function in acf/init

Am trying to get the ID of single product page inside my function but it's returning bool(false) or NULL.
What am trying to achieve is to get the ID to filter the categories taxonomies terms of a specific product and display it in a tab using ACF but unfortunately am not able to get the ID.
I have the global $post code working in the meta box I added for the single products edit page so I'm not sure what am missing here.
Below is my code:
function my_acf_add_local_field_groups() {
global $post;
var_dump($post); // returns NULL and bool(false) when echo'd
acf_add_local_field_group(array(
'key' => 'tab_group_1',
'title' => 'Product Sizes and Prices',
'name' => 'group_sizes_tab',
'fields' => array (
array (
'key' => 'field_tab_size_1',
'label' => 'First Size',
'name' => 'store_sizes_',
'type' => 'tab',
'parent' => 'tab_group_1',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => '',
'max' => '',
),
array (
'key' => 'field_unique_key',
'label' => 'Simple Repeater',
'name' => 'simple_repeater',
'type' => 'repeater',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => 0,
'max' => 10,
'layout' => 'table',
'button_label' => 'Add row',
'sub_fields' => array (
array (
'key' => 'field_unique_key_1',
'label' => 'Total Products',
'name' => 'total_products',
'type' => 'text',
),
array (
'key' => 'field_unique_key_2',
'label' => 'Total Prices',
'name' => 'total_prices',
'type' => 'text',
),
),
),
array (
'key' => 'field_tab_size_2',
'label' => 'Second Size',
'name' => 'store_sizes_2',
'type' => 'tab',
'parent' => 'tab_group_1',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => '',
'max' => '',
),
),
'location' => array (
array (
array (
'param' => 'post_type',
'operator' => '==',
'value' => 'products',
),
),
),
));
}
add_action('acf/init', 'my_acf_add_local_field_groups');

How to add custom fields in ACF programmatically?

I want to programmatically add a tab with repeater inside but I can't seem to find a solution, I've googled all available resources but still not working.
I already tried using acf_add_local_field_group and acf_add_local_field but still no luck.
Well I can create a tab using acf_add_local_field but when I tried to add a child which in this case a repeater OR even a text field it still doesn't work.
Here's my code to create a tab and its child but the child doesn't work.
acf_add_local_field(array(
'key' => 'field_1',
'label' => 'Sub Title',
'name' => 'sub_title',
'type' => '',
'parent' => 'field_5bd14c9349930',
'fields' => array (
array(
'key' => 'field_2',
'label' => 'This is a test',
'name' => 'my_test',
'type' => 'text',
)
)
));
You should use acf_add_local_field_group to construct the whole field group.
Here's the proper code for adding a group and a custom tab with single repeater field inside:
if( function_exists('acf_add_local_field_group') ):
acf_add_local_field_group(array (
'key' => 'group_1',
'title' => 'My Group',
'fields' => array (
array (
'key' => 'field_unique_key',
'label' => 'First Tab',
'name' => '',
'type' => 'tab',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'placement' => 'top',
'endpoint' => 0,
),
array (
'key' => 'field_unique_key',
'label' => 'Simple Repeater',
'name' => 'simple_repeater',
'type' => 'repeater',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => 0,
'max' => 10,
'layout' => 'table',
'button_label' => 'Add row',
'sub_fields' => array ( // Here you can add as many subfields for this repeater as you want
array (
'key' => 'field_unique_key',
'label' => 'Link',
'name' => 'link',
'type' => 'link', // example link type
'instructions' => 'Link name and URL',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'return_format' => 'array',
),
),
),
),
'location' => array (
array (
array (
'param' => 'post_type',
'operator' => '==',
'value' => 'post',
),
),
),
'menu_order' => 0,
'position' => 'normal',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
));
endif;

get acf fields from php file

I put this code into my functions.php
include_once('advanced-custom-fields/acf.php');
include_once('acf-options-page/acf-options-page.php');
include_once('acf-repeater/acf-repeater.php');
define( 'ACF_LITE', true );
if(function_exists("register_field_group"))
{
register_field_group(array (
'id' => 'acf_options',
'title' => 'Options',
'fields' => array (
array (
'key' => 'field_525d1b6d49043',
'label' => 'lable',
'name' => 'homepage',
'type' => 'repeater',
'instructions' => 'Select which categories you want to display on the homepage.',
'sub_fields' => array (
array (
'key' => 'field_525d1b8a49044',
'label' => 'Category',
'name' => 'firsttext',
'type' => 'text',
'column_width' => '',
'field_type' => 'text',
'return_format' => 'id',
),
array (
'key' => 'field_525d2473de72c',
'label' => 'Number of Posts',
'name' => 'number-of-posts',
'type' => 'text',
'column_width' => '',
'default_value' => 4,
'placeholder' => '',
'prepend' => '',
'append' => '',
'min' => 2,
'max' => '',
'step' => 2,
),
),
'row_min' => 1,
'row_limit' => 1,
'layout' => 'row',
'button_label' => 'Add a category',
),
),
'location' => array (
array (
array (
'param' => 'options_page',
'operator' => '==',
'value' => 'acf-options',
'order_no' => 0,
'group_no' => 0,
),
),
),
'options' => array (
'position' => 'normal',
'layout' => 'no_box',
'hide_on_screen' => array (
),
),
'menu_order' => 0,
));
}
Then I enter values into fields in admin console
How I cat get this value from page file?
I try get_field('acf_options) and I try get_field('homepage), but this return null
Im not sure why you would want to put this in your function.php file instead of just do this this through the plugin.
But if you want to retrieve those field values, you should do this: get_field( 'homepage', 'option' );
instead of:
get_field( 'homepage' ) or get_field( 'acf_options' );
My best advice would be to look on the ACF website for information. These docs help out a lot!

Resources