Comments (11)
Hi @drzraf
Thanks for the question. I'm happy to help with this and believe the issue is quite simple.
The .xml example you provided contains 2 meta values, these are 'sources' and 'sources_0_url'.
Alongside each 'value', ACF also saves a 'reference' which is used to find the field for a given meta value.
For example, you would expect to see this for each value:
'sources' = 1
'_sources' = 'field_123'
My question is, why doesn't your .xml example contain these meta rows?
- Does your .xml export tool ignore meta keys that start with an underscore?
I believe that if your .xml file contains the correct "reference" values, they shoudl import correctly and the ACF functions (such as get_field and have_rows) will continue to work as they should.
I don't believe there is any specific issue here with the wp_insert_post()
function, but I'm happy to hear more about this.
if you believe there is an issue from ACF's end, please setup a working example so we can both login and experience the problem first hand.
from acf.
The reference does not exists because the import file is the result of an export from a Drupal 7 CMS using custom tool.
When new post is inserted (whether from a WXR import, a CSV, or other programmatic mean), one would commonly provide ACF meta fields (using the format expected by ACF), but is unlikely to create "reference" fields because of their unpredictable nature (and the fact that during data transfer, a WordPress may be partially configured (plugins disabled, ACF fields unsynchronised or not registered yet, or fields may even have been registered simultaneously on two different instances (developer vs -prod) so reference are not the same, ... ...)
Since ACF can autogenerate them without problem when saving through the admin UI, I'd expect a function to exist to do the very same job using the internal WP/ACF API.
I'd even expect wp_insert_post()
to trigger hooks that do that automatically.
The issue can be easily reproduced by
$id = wp_insert_post( [
'post_content' => 'foo',
'post_title' => 'bar',
'post_status' => 'publish',
'post_type' => 'page' // ACF field named "source" (a repeater of links fields) is registered/enabled for "page"
] );
add_post_meta(368, "sources", 1);
add_post_meta(368, "sources_0_url", serialize(["title" => "BBC NATURE", "url" => "http://www.bbc.co.uk/nature/foo"]), 1);
print_r( get_field( "sources", $id ) );
/* expected:
Array
(
[0] => Array
(
[url] => Array
(
[title] => BBC NATURE NEWS
[url] => http://www.bbc.co.uk/nature/foo
[target] =>
)
)
)
*/
/* actual:
1
*/
// Ok, then we expect to insert the post again in order to trigger ACF handlers so that (as with the admin UI) reference fields will be regenerated:
wp_insert_post( get_posts( $id ) );
print_r( get_field( "sources", $id ) );
/* actual (even less expected)
1
*/
from acf.
Hi @drzraf
Thanks for the reply and clarifying how the .xml file was created.
This is definitely something we can look into in the future, but currently, there is no magic code that looks up and creates the "field references" during the 'save_post' or 'insert_post' actions.
These references are not random, but are infact the field's keys. If you load a field, you can access it's key. This is similar to a post and it's ID.
ACF is able to save these references correctly during the "Admin UI save" because they are included in the $_POST data.
This would be hard to do "magically" because multiple field's can have the same name.
Please note that ACF can still function without these "reference values". The get_field()
and have_rows()
functions will be able to lookup the field using it's name (instead of the key). If the field is found, everything will work as expected.
The only issue with this is that ACF allows multiple fields to have the same name, so there is a chance for failure using this "name lookup" approach - hence the need for saving the reference values in the first place.
This isn't something that I will be looking to investigate in the short term, so if you are in need of a solution now, I suggest that you hook into the "save_post" or "insert_post" WP actions and use the meta data to lookup ACF fields (using the get_field_object function) and then create the reference value.
Please take a look inside the ACF core code for the acf_update_value()
function which will help show how to create the reference.
Thanks
E
from acf.
The get_field() and have_rows() functions will be able to lookup the field using it's name (instead of the key). If the field is found, everything will work as expected.
but not with repeater then?
function remap_acf( $post_id ) {
// xxx() finds ACF registered for that post and returns an associative array of $field_reference => $field_name
$fields = xxx( $post_id );
// ensure $field_name is unique among $fields (to avoid the risk of conflict) and abort otherwise
foreach( get_post_meta( $post_id ) as $key => $value ) {
if ( in_array( $key, $fields, TRUE ) ) {
add_post_meta( $post_id, "_" . $key, "field_" . $field_reference, TRUE );
}
}
}
That xxx()
function is probably similar to the one generating the <input>
(to be posted in the admin UI).
from acf.
Hi @drzraf
Thanks for the reply.
I've just spent some time looking through the ACF template functions to better understand the issue and believe I have discovered a bug.
Contrary to my belief, ACF is not providing a 'fallback' lookup technique to find field's via their names.
This explains why the get_field()
and have_rows()
functions are not working as expected for your data.
Can you please help test this bug by editing the function acf_maybe_get_field()
located in the "includes/api/api-field.php' file and change the 3rd parameter from $strict = true
to $strict = false
With this parameter default set to false, ACF should now be able to find the field object using just it's name.
After making this change, can you please test your issue and let me know if things start to work as expected.
from acf.
I just had the opportunity get on this again. The change you suggested made it! Thank you!
(But the change was not part of 5.7.2)
from acf.
Hi @drzraf
Thanks for the reply and PR.
I introduced this change back in 5.7.0 and had to revert it later in 5.7.1.
Unfortunately, this change causes issues with the get_field()
function whereby the 'default_value' of a field is returned instead of null
.
I'm happy to look into this again in the future, but won't have any time at the moment.
from acf.
Don't you want to reopen to avoid forgetting it? (See also #54)
from acf.
Hi @drzraf
Sure. I'm happy to re-open this ticket, but am unsure when I will be able to look into it.
I have a lot of plans for improving the core foundations of ACF and will hopefully be able to address this limitation then.
from acf.
Hi @elliotcondon ,
I got bitten again by this one today. Could you point me to the issue that forced you to revert $strict
?
I'd be glad to help solving this one in some way (maybe even via a configurable hook?)
from acf.
Hi @drzraf
I believe the particular ticket is over on our Helpdesk (not GitHub), so i won't be able to share with you the exact details, but I am happy to discuss the issue.
There were two main issues found when changing the $strictparameter from
trueto
false`.
1. Incorrect formatting.
When you load a value via the get_field()
function, ACF attempts to find the "field" that is connected to that value. In an optimal case, the field is called "home_hero_image" and is the only field with this name. Loading this field is safe and accurate.
The problem occurs when two or more fields use the same name, for example "image". Although these fields share the same name, they have completely different settings, and maybe are even different field types.
If the lookup is not strict, ACF may incorrectly find the wrong "image" field (because it will lookup via name, not key). This can lead to incorrectly formatted values.
2. Default values.
As a flow on effect from the issue above, this change allowed a field to be found even if no "meta" value existed for the given post.
For example, if a new post was created, but no value was entered into the "image" field, ACF would incorrectly find a field called "image" and attempt to "format" the null value.
This would change the null value to a string, int, or other data structure. This caused many complaints from developers who's if
statements failed to work as normal.
from acf.
Related Issues (20)
- When returning false in acf/load_field or acf/prepare_field multiple warnings occur HOT 1
- ACF post preview and revisions completely broken HOT 8
- WYSIWYG 'visual' tab in sidebar breaks when switching sidebar tabs HOT 1
- WYSIWYG Editor Field: Image element with width and height attributes triggers unsafe HTML error message HOT 4
- filter wysiwyg_tinymce_settings breaking HOT 1
- Front-end form submits itself when closing the wordpress link-edit dialogue
- Nested cloned repeater only works for 1 level
- Gallery - edit image breaks field in block sidebar HOT 1
- ACF 6.3.0 update breaks "No fields assigned" filter with empty string HOT 3
- Can't add ACF licence key HOT 1
- update_field() not working as expected in this scenario HOT 3
- Installing through composer installs incorrect version HOT 5
- Uncaught TypeError: Cannot access offset of type string on string - flexible content HOT 4
- Fix jQuery deprecations HOT 1
- User field stopped showing in GraphQL query
- Group: image subfield nĀ°10 not working HOT 1
- PLEASE ADD A DISCLAIMER THAT SHORTCODES HAVE TO BE ENABLED NOW HOT 1
- Repeater field type with pagination HOT 1
- Conditional logic in the Advanced Field Settings broke when a wrapper was added v6.2.9.
- Ampersands in Text Area fields produce warnings HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ššš
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ā¤ļø Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from acf.