Support

Account

Home Forums ACF PRO Retrieve most recent front-end edited fields?

Solving

Retrieve most recent front-end edited fields?

  • Here is my scenario:

    I have a repeater field on my posts. It allows users to be able to fill out info (a couple text fields and an image upload) on the front-end when my posts are published. And then within the single.php template, I am able to display the results of the repeater field as users enter content.

    This works great, however I am wondering how I would query the WordPress database to display the most recent user entered info on the homepage of my site. So I would want to perform query that grabs the most recent user submitted info on my posts and then display it on the homepage.

    Would I need to add a hidden field to the custom fields that are part of the repeater field that would be a timestamp of when the user submitted the info? And then somehow comb through the user submitted info and grab the most recent ones?

    I am just trying to figure out the least intensive way of doing this.

  • You’ve pretty much got it. Custom fields are not dated in any way so you’ll need to create some way to know when they were added or changed. And since it’s a repeater the only way to figure out what the date on each row is will be to loop through the repeater an check the date.

  • Okay, thanks.

    This makes sense.

    However, where I am getting stuck is being able to loop through the repeater field attached to the posts to determine the most recent additions. Here is what I need to do:

    1) Query the last 10 (let’s just use 10 for now) posts
    2) Loop through the repeater field in each of those posts to grab the rows for each post
    3) Sort all the rows according to date
    4) Display the rows on the homepage in a “most recent” order

    So would it be best to grab the rows for the repeater field for each of the posts and throw them in an array. And then sort the array according to the hidden timestamp field? Something like below?

    http://stackoverflow.com/questions/6401714/php-order-array-by-date

  • For something as complicated as this, I’m going to be honest, I would use something a little more drastic because querying all the posts and then looping through every repeater of every post is going to be a time suck and impact the performance of your site.

    I have an idea for a better approach that does not include doing any queries on posts or looping of repeater fields, but it depends on what you’re looking to keep track of.

    Give me more details about the repeater and sub fields that you want to track and what you want to display on the home page and I’ll give you an example using that information.

  • Hi John,

    Thanks so much for your willingness to help out!

    Basically I will be posting blog posts and then allowing users to be able to upload an image and description to each post (image field and text area field).

    I was thinking this would be a repeater field with those two sub fields so that they could easily be displayed as more and more users add to the post.

    And then on the homepage, I wanted to have some way to display the most recent user submissions (to any post).

    Does that make sense? Do you know an easier way I could accomplish this?

    Thanks!

  • Sometimes I find things interesting and believe it or not, this type of coding is what I do to relax. I’ve done this in OOP because it’s the way I think.

    I’m not sure if there are any errors, I have not tested this. It’s not meant to be exact but it’s easier to give a code example than to explain all the details.

    
    <?php 
      
      /*
          store updated values for a repeater
          so they can easily be used elsewhere
          
          This specific class will save new values
          for new images added to a repeater
          there should only be 1 image field in the repeater
      
      */
      
      new for_kkranzo_store_recent();
      
      class for_kkranzo_store_recent {
        
        // this will store any updates that are made
        private $new_content = array();
        
        // a WP option name value were you can store updated content
        private $option_name = 'for_kkranzo_store_recent';
        
        // this will hold images that were added in the past
        private $old_images = array();
        
        // set the maximum number of entries to save in recently added
        private $max = 10;
        
        // name and key of the repeater field
        private $repeater = array(
          'name' => 'my_repeater_field',
          'key' => 'field_XXXXXXXXXXXXX'
        );
        
        // name and key of the image sub field
        private $image_field = array(
          'name' => 'my_image_field',
          'key' => 'field_XXXXXXXXXXXXX'
        );
        
        // sub field key => name pairs
        // don't include the image field
        private $sub_fields = array(
          'field_XXXXXXXXXXXXX' => 'my_field_1',
          'field_XXXXXXXXXXXXX' => 'my_field_2'
          // etc...
        );
        
        // array of all of the sub fields you want to store
        
        public function __construct() {
          
          // add a filter that runs before ACF saves values
          add_filter('acf/save_post', array($this, 'before_acf'), 1);
          
        } // end public function __construct
        
        public function before_acf($post_id) {
          // this filter will be called before ACF saves new values
          
          // first make sure the repeater is set in $_POST
          // if not the we don't need to do anything
          if (empty($_POST['acf'][$this->repeater['key']])) {
            return;
          }
          
          // get all the existing images for this post
          // and store them to compare against
          $rows = get_field($this->repeater['name'], $post_id, false); // no formatting
          foreach ($values as $row) {
            $this->old_images[] = $row[$this->image_field['name']];
          } // end foreach rows
          
          // now loop trough the submitted values to see if there are new ones
          foreach ($_POST['acf'][$this->repeater['key']] as $row) {
            // see if this image is old
            // if it is then continue to the next one
            $image = intval($row[$this->image_field['key']]);
            if (in_array($image, $this->old_images)) {
              continue;
            }
            
            // new image - save it
            $new = array(
              'post_id' => $post_id,
              'attachment_id' => $image
            );
            foreach ($this->sub_fields as $key => $name) {
              $new[$name] = $row[$key];
            } // end foreach sub field
            
            // add the new content to the list
            $this->new_content[] = $new;
            
          } // end foreach row
          
          // if there was nothing new then bail
          if (empty($this->new_content)) {
            return;
          }
          
          // get the old option, if anything
          $option = get_options($this->option_name, array());
          
          // merge the old array onto the new array
          $option = array_merge($this->new_content, $option);
          
          // strip it down to the max number to save
          $option = array_slice($option, 0, $this->max);
          
          // save the new option
          update_option($option, $value);
          
          // now wherever you want to show the new values
          // you can get this option and you have a reference to
          // the post id, the attachment id and any of the other
          // field values you want to display
          
        } // end public function before_acf
        
      } // end class for_kkranzo_store_recent
      
    ?>
    
  • Wow, that is great. I didn’t realize the answer would be so involved!

    Now I will throw this at you ;)…

    I was thinking through this some more and was wondering if the easiest way would be to just create a custom post type of “Image Uploads” and then do the following:

    – Each “Image Uploads” custom post type post would have the repeater field with the text area and image upload sub field and also a custom field that would be called “Associated Post”.

    – When a regular post was created on the site, a new “Image Uploads” post would be automatically created as well. And the regular post would store the ID of the newly created “Image Uploads” post (in a custom field called “Associated Image Uploads”) and vice versa (the newly created “Image Uploads” post would store the value for the regular post in the “Associated Post” field). That way they would both know they are associated with one another.

    – Then, when the regular post is displayed on the site I would be able to query that single custom post type “Image Uploads” post to display the images (using the ID stored in the “Associated Image Uploads” field).

    – And then on the homepage, I would be able to just query all “Image Uploads” post types by most recent.

    What are your thoughts on this method? Seems a lot less involved!

    The only thing I am trying to figure out is how to associate the two posts together. So here are my questions:

    1) How can I create a custom field on the regular post that would know the ID of the to-be-created “Image Uploads” post?

    2) And similarly, how would I be able to have a custom field on the “Image Uploads” post that would know the ID of the post that created it?

    It seems like I would need to create some kind of custom function that would run after a regular post is published that would automatically create the “Image Uploads” post and then update the regular post with that new “Image Uploads” post ID and also update the newly created “Image Uploads” post with the ID of the regular post that was just published. Correct?

    Hopefully this all makes sense!

    Thanks again for your help.

  • My thoughts is that it’s a far more complicated way of doing things. When I develop my goal is to make things simpler, for both the user and myself, and I look for the easiest solution to the problem that accomplishes what I need to accomplish.

    as for your question

    1) How can I create a custom field on the regular post that would know the ID of the to-be-created “Image Uploads” post?

    2) And similarly, how would I be able to have a custom field on the “Image Uploads” post that would know the ID of the post that created it?

    the answer to both of then is “none that I know of”.

    It might be possible to move the uploaded images to a new post after they were uploaded and create the new post then and then update the post being saved. But like I said, seems like a lot of work when all you really want to do is display the newest values on the home page.

  • Gotcha.

    The only problem is that I need to display the most recent uploaded images, however I also need to know which regular post those images are associated with (the uploaded images are essentially sub image fields within a repeater field on that regular post).

    I’ll look into a way to automatically publish a new custom post type post once a regular post type is created. And then, once that new custom post type post is created, the ID of that post can get updated within the regular post and the ID of the regular post get get updated within the newly created custom post type post.

  • This reply has been marked as private.
  • This reply has been marked as private.
  • This reply has been marked as private.
Viewing 13 posts - 1 through 13 (of 13 total)

You must be logged in to reply to this topic.