Support

Account

Home Forums Add-ons Flexible Content Field Latest version: critical endless loop crashes sites

Solved

Latest version: critical endless loop crashes sites

  • Hi
    Posting for the first time, have been using ACF since the very beginning all years with no problem. But now there is a huge one.

    After updating to the latest version today (We are little late…) All our Themes and WordPress application crashes, that are using repeater addon and Flexible content.

    The problem we think is that the new version says:

    note: you don't need to specify the $post_id for any sub field functions

    But now the subfield are re-using the first post id passed in the architecture of our functions and template setup. Our system has been working perfectly until this update. Around 100 clients and 200 -300 running projects are right now affected.

    CORE: The repeater includes a flexible content setup, and now, somwhere in the chain the global $post ID is re-used.

    This start the flexible content to use the sub fields of parent. And in our case, the post fields start including the loaded post itselfs.

    The idea to use this plugin is the strenght of idea to “repeat” and map around the custom fields. = You can create apps and web “softawares” with WordPress + ACF + addons like flex and rep.

    We must get the new verion to work as the one before. HOW?

    Here is one example of a structure:

    
    LOADED PAGE/ POST 
    
    // Main post loop
    - the_content() and stuff
    - and calling my_output_html(get_the_ID());
    - more other stuff
    // End post loop
    // Sidebars
    are also using my_output_html(some id);
    //
    
    THIS FUNCTION IS CALLED BOTH INSIDE AND OUTSIDE LOOP, in functions.php
    
    function my_output_html($id = false){
    	if(!$id) $id = ua_current_post_id(); // Get root id (page loaded)
    	while(has_sub_field('repeater_field_master', $id)){
    
    			if(get_sub_field('repeater_field_1')){
    				if(get_sub_field(... do something
    				if(get_sub_field(... do something
    				if(get_sub_field(... do something
    
    				And THEN comes a flexible content field, (in the repeater)
    				while(has_sub_field('FLEXIBLE_CONTENT_ROOT', $id)){ <-- FAILS SECOND CALL to my_output_html($id)
    					
    					if(get_row_layout()...
    					if(get_row_layout()...
    					ETC ETC and :
    					
    					if(get_row_layout() == 'include_posts'){ 
    						if(get_sub_field('posts')){
    							foreach(get_sub_field('posts') as $p){
    								$inc_id = $p->ID;
    								if($inc_id == $pid) { break; } // Do not allow root id to include itself
    								my_function_render_included_post($inc_id);
    
    function my_function_render_included_post($inc_id){
    
    	$obj = get_post( $inc_id );
    	echo $obj->post_title;
    	and output its content, calling their own ACF custom fields.
    	Should this post include another post? YES
    	
    	Calling :
    	
    	my_output_html($obj->ID);
    }
    

    SUMMARY

    This setup let us use post as widgets, and each widget can include other widets, post or pages. And each unique page can include widgets…

    Thanks for checking this up / Jonas Lundman, Intervik

  • Hi @intervik

    Thanks for the post, but I’m quite confused as to what the issue actually is.

    You mention at the start that this statement is a raise for concern:
    “note: you don’t need to specify the $post_id for any sub field functions”

    Where is this statement found, I cant find it…

    When looping through a nested has_sub_field function, the $post_id is never needed because it is loading data from the already setup previous loop.

    Is this the issue?:
    while(has_sub_field('FLEXIBLE_CONTENT_ROOT', $id)){ <-- FAILS SECOND CALL to my_output_html($id)

    What is FLEXIBLE_CONTENT_ROOT? Why is ROOT in it’s name. Is this within a repeater or outside a repeater?

    You mention that it fails to call my_output_html. But there is no code which runs this in the nested loop…

    Also, why do you say:
    “CORE: The repeater includes a flexible content setup, and now, somwhere in the chain the global $post ID is re-used.”

    I guess there is a lot of information to tell, but please do in a clear and flowing way. The above is more of a mental dump which is very hard to understand what the exact issue is.

    Thanks
    E

  • Hi and Thanks for answering and for your time!
    To simplify a little:

    “note: you don’t need to specify the $post_id for any sub field functions”

    This is in your documentation, for the new version of ACF. We think this change is the problem.

    When we rolled back ACF one step, everything works again.

    The structure example posted before, is not a real function, just a ‘dummie’. Our setup is very complex and hard to explain. But I try:

    EVERY POST have the exact same ACF setup fields:

    The Repeater has a subfield with a Flexible content with layouts, and in one layout a relationship post object field.

    This is what we accomplish:

    Every post and page has the same Repeater. With this we build the content below the standard editor. And a post can include another post(s) repeater-content, and that post can include repeater-content from another post… No depth limit, but a post id can never be include itself in each chain.

    We are not using widets. We are using posts. Example: One post using ACF Gallery and location field (in the repeater). We wanna re-use this post as a widget.

    Example: The main query POST “Delayed travels” says (in the repeater):

    Include POST Gallery on Sidebar 2 on top, and
    Include POST Airport Links on Sidebar 3 …

    Then the latter POST Airport Links, says: (in its own repeater field)

    Include POST Airport Germany links on Below main content
    Include POST Airport Sweden links on Below main content
    Include POST Airport Sydney links on Below main content
    Include POST Airport New Zeeland links on Below main content

    This is done with a simple output strategy. The Main post ( the page ) is using the wp single.php template, and the loop. Thats where the reading of the ACF fields starts. But it passes the post ID to a FIRST function with its own scope. Every post object called from here are NOT using any templates for output the html. Its done in a second function who echoes out its HTML. If this has repeater content, this posts id are passing up to the FIRST function. Its standard script function pass to unique scope.

    The key is to pass the ID to the FIRST function that holds “while has subfield”, and all the stuff to see if any post objects are gonna be included after rendering its own content.

    This scope is not unique anymore, couse ACF starting to use sub fields from the loop (where it all begins). WE THINK…

    Here is the REAL PHP the beginning of the 2 main functions and the loop.

    
    //MAIN LOOP
    the_content();
    $extra_content = get_field('activate_content_below', get_the_ID());
    if($extra_content) whatever(get_the_ID()); 
    // END MAIN LOOP
    
    This is in functions.php
    // unique scope :
    function whatever($id){
    	while(has_sub_field('ua_acm_rf_master', $id)){
    		if(get_sub_field('ua_acm_rf_activate')){ // true or false switch
    			while(has_sub_field('ua_acm_rf_fc_master', $id)){
    				if(get_row_layout() == 'ua_acm_rf_fc_post_include'){ 
    					if(get_sub_field('posts')){
    						foreach(get_sub_field('posts') as $p){
    							$inc_id = $p->ID;
    							ua_post_this($inc_id); <-- REMARK NEW ID
    
    							
    // unique scope :							
    function ua_post_this($inc_id){
    	$obj = get_post( $inc_id );
    	echo '<h1>'.$obj->post_title ... and so on
    	
    	Now, we check if THIS post have som ACF field, calling the SAME function as the LOOP did.
    	$extra_content = get_post_meta($inc_id, 'activate_content_below', true); 
    	if($extra_content) whatever($inc_id); <-- RE-USING FIRST FUNCTION
    }
    

    Im shure its a small, tiny change like global $something that destroys this setup. But the worrying part is that we are completley building with ACF, and it is a Huge invested time in this modular building setup. We must get it to work and keep up with latest versions…

    Many many thanks for looking in to this.

  • Hi @intervik

    Thanks for the follow up.

    Can you please be specific where this statement is in the documentation? The one about $post_id?

    Please note that $post_id has never been a param of get_sub_field or the_sub_field, or if it has, it was a very very long time ago.

    Have you debugged your code? Using a basic print_r and die method, you can test each line of coded and find the actual line where the ‘infinite loop’ starts.

    Also, you mentioned a ‘rolling back’. can you please specify which versions of ACF you had before / after the issue?

    Thanks
    E

  • Hi!
    Great support for this issue. Thanks.

    Working version is Versions:
    4.2.2 ACF Core
    1.0.2 Flexible Content Field
    1.0.1 Repeater Field

    Wondering what this is:
    What’s new

    Core: get_field can now be used within the functions.php file

    If you could not before, something with the scope should have been changed?

    We are in the middle of late working nights right now to rollback all the projects that been affected by the auto update by the admins all over. ACF has a hight update freq, and has Always been stable, relyible. Its one of the few plugin we update without do the testdrive on each install first.

    As soon as p, within a few days, I will do the die() trace, but it so much easier if we get a understanding of the changes in the latest version. This is where we need to track what the latest update does diffrently:

    // loop
    $other_page = get_the_id();
    doit($other_page)
    
    function doit($other_page){
     while(has_sub_field('repeater_field_name', $other_page))
      if(get_sub_field('sub_field_1')){
       while(has_sub_field('flexible_field_name', $other_page))
        if(get_row_layout() == 'row_name_1'){
         if(get_sub_field('posts')){
          foreach(get_sub_field('posts') as $p){
           $new_other_page = $p->ID;
            goto_function_write_post($new_other_page);
    
    function goto_function_write_post($new_other_page){
     $obj = get_post($new_other_page);
     $other_page = $obj->ID;
      $ACF = get_post_meta($other_page, 'repeater_field_name', true);
       if($ACF) doit($other_page);
    }
    

    It is a brain resoucing procedure … If you cant see anything particular in this chain that might couse a global scope, then give me a hint.

    Otherwise I come back within a few days and report my tracking / comparing versions output, and we go from there with this thread.

    Thanks so far!

  • I searched for some keywords before reporting an issue submission and found this post.

    The OP indicates similar behavior to what I am experiencing:

    • after updating to 4.3.0 from 4.2.2 (and to latest FC and Rep add-ons from 1.0.2 and 1.0.1 respectively) a page now renders very differently. Specifically, media images stored as a sub-field in a repeater field are now showing blank due to has_sub_field function returning false semi-randomly.
    • I also came across “note: you don’t need to specify the $post_id for any sub field functions” in documentation. It appears in sample code on http://www.advancedcustomfields.com/resources/functions/has_sub_field/

    Use Case:

    1. Multiple posts created using the same ACF template.
    2. Gallery page loops through the posts to display them as a list.
    3. Every third post fails to show an image stored in the first sub-field (of two) of a repeater field.

    Code:`
    $profile_pic = get_field('profile_pic', $post_id);

    echo( “Post ID: ” . $post_id . “</br>”);
    echo( “Profile_pic repeater field: “);
    print_r($profile_pic);
    echo “</br>”;

    if (has_sub_field('profile_pic', $post_id)) {
    $attachment_id = get_sub_field('media_library_image');
    $url_link_image = get_sub_field('url_link_image');
    …`

    Debugging:
    I narrowed the issue down to the has_sub_field() call. It returns false (every third post?!) even though print_r and var_dump statements to screen and log clearly show the repeater field has a sub_field.

    *On pages where a single post is displayed, the image always shows.
    *On the page where multiple posts are queried, every third image is blank.

    After pure confusion for a few hours now, I also started to feel like the post_id is not “clearing” itself between new calls to has_sub_field.

    Temporary work-around:
    Since I know every post I am query has populated sub-fields, only solution (and risky one) is to directly access the array (e.g. $attachment_id = $profile_pic[0]["media_library_image"]; Everything shows up properly with this hack.)

    General question:
    How can I reset a call to has_sub_field so that I start again at first element of repeater field list (even if I have not reached end yet)? Sequential has_sub_field calls:`has_sub_field('profile_pic', $post_id
    has_sub_field('profile_pic', $post_id)`
    versus`has_sub_field('profile_pic', $post_id)
    has_sub_field('profile_pic', $post_id)
    has_sub_field('profile_pic', $post_id)`
    produced an ON/OFF effect.

    Environment:
    WP 3.7.1
    ACF 4.3.0

    —–
    Side note: I can understand the initial confusion OP may have with “note: you don’t need to specify the $post_id for any sub field functions” comment in documentation since has_sub_field is demonstrated both with and without use of the post_id parameter.

  • Hi @bsy-web

    Thanks for the data!
    I’ll attempt to recreate the issue today and fix any loop issues with the has_sub_field function

    Thanks again

    Cheers
    E

  • For my environment, I narrowed the issue down to the ACF core update alone (no other changes to WP and ACF add-on versions).

    Working:
    WP 3.6.1
    ACF 4.2.2
    ACF:Flexible Content Field 1.0.2
    ACF:Repeater Field 1.0.1
    ACF Repeater Collapser 1.1.0
    ACF Support for Custom Post Templates 1.0
    Custom Post Templates 1.5

    Status after updating:
    ACF 4.2.2 -> 4.3.0 :
    Page renders differently as described in earlier post. has_sub_field returning false for specified repeater field.

    Status after manual rollback:
    ACF 4.3.0 -> 4.2.2 :
    Page returns to expected rendering.

  • Hi guys

    Great news.

    I have been able to reproduce and fix the issue completely!
    The key was that only the 3rd post would contain the incorrect data. This lead me to find that the logic within the function was incorrectly looking at the data, and have now fixed it completely!

    This was a great bug find and you can download the fix from github. A new version should be out shortly too

    Thanks
    E

  • Hi,
    sounds great. Where is this on Github? Would like to test it so I can report this as solved for all my clients.

  • Hi,
    Problem NOT solved. The only thing that has changed is that the server itself doesnt shut down, but the page try to load in infinity loop/ just spinning.

  • I tried to track the issue a little. I let the browser spinn 20 min until it stopped. The third content was rendered 200 times…

    The third nestled get_sub_field “belives” it has its parents sub_field.

    It is called within while(has_sub_field(flexible, $current_id)

    so all get_sub_field() “below” this $current_id should be unique, but its not.

    if finds a subfield, and when I echo the id within, that post id has no subfield data (but the parent had)

    Maybe your fix was not complete:

    Im not using a repeater who has a repeater who has a repeater…

    my setup is

    a repeater has a flexible content field who has a repeater who has a flexible who has a repeater who has a flexible …

    Im feeling a little bit sorry for you, I know how it is when you think something might be solved, and you have to brainstorm again…

    Thanks for your work

  • The latest version, 4.3.1, resolves issue for my setup. Page with issue is now rendering exactly as with ACF 4.2.2.

    My layout and loop sounds less complex than @intervik‘s. It is a single loop, which can run at most one time, and lists multiple posts containing the same set of custom fields.

    Confirmation procedure:

    1. Delete all cached versions of troublesome page. I wasted a lot of time in debugging and confirming the fix just due to resilient caching schemes.
      • Turn off all caching plug-ins.
      • Manually delete wp-content/cache directory.
      • Delete browser cache.
    2. Load page with ACF 4.2.2 -> PASS
    3. Replace ACF 4.2.2 with ACF-master from GitHub
    4. Load page with ACF-master (4.3.1) -> PASS
    5. Replace ACF-master (4.3.1) with ACF 4.3.0 from GitHub
    6. Load page with ACF 4.3.0 -> FAIL (as expected; sanity check)
    7. Replace ACF 4.3.0 with ACF 4.3.1 from WordPress plug-in page
    8. Load page with ACF 4.3.1 -> PASS

    @elliot, thanks for the quick turn-around on this.

    BTW, any way to append version number on WordPress hosted file, e.g. “advanced-custom-fields-4.3.1.zip”? It helps to quickly identify needed version of file and fast to archive without extra edit (and chance of label error) on user’s part.

    Peace

  • Hi @intervik

    Can you please expor the field group to PHP and include the code (perhaps zip it in .php file first) and attach it to a comment?

    i would like to use your exact field setup to test the code on.

    Thanks mate, we’ll have this fixed shortly.

    Thanks
    E

  • Hi
    zip attached:

    I created a zip with the export and some images, also the 2 main functions using the setup + XML version of the ACF export. Some notes in the files. The picures shows how it looks in the backend and frontend to understand what we are doing…

    This setup has been working fine using ACF many years, and implemeted in the repeater some yars ago, always working superb version after version..

    / sad but hopeful Koala

  • Hi @intervik

    Thanks for the .zip, can’t thank you enough. I’ll take a look at this tomorrow and hopefully have a solution quickly.

    Thanks
    E

  • Hi @intervik

    Thanks again for all your great help with fixing this bug. I just wanted to let you know I have tracked the bug to a conditional statement in the have_rows function.

    Basically, the logic got confused due to multiple posts and multiple repeater levels!

    Good news is the fix was very simple and you can find it on github!

    If you wish to apply the fix manually, please edit the ‘core/api.php’ file on line 405 and change:

    from

    
    if( $prev && $prev['name'] == $field_name )
    

    to

    
    if( $prev && $prev['name'] == $field_name && $prev['post_id'] == $post_id )
    

    Thanks again!

    Cheers
    E

  • Hi!
    I just tested the latest update and it seems to work fine. Thanks for the smooth and fast soution and fix. One line with an extra statement, well “size matter” after all….

    Superb, marking this as solved.
    / Jonas

Viewing 20 posts - 1 through 20 (of 20 total)

The topic ‘Latest version: critical endless loop crashes sites’ is closed to new replies.