1

Okay so I'm using Magic Fields 2 on an old WordPress project (rather than ACF unfortunately) and I've got some confusion happening while I'm writing PHP.

Basically I'm on a page template that calls the Magic Fields group from it's post ID because the fields themselves are on a custom post type. They're just being displayed on a page template.

Then I'm looping through that group's fields to get an ID value that is just choosing another post with the Magic Field's Related Type field.

Now here's my problem after using var_dump to debug - instead of giving me the ID value for EACH post chosen with the related type (there's currently two) - it's repeating the first ID twice.

This to me is a PHP question versus Magic Fields. So how do I get EACH ID value within the existing foreach without resorting to another foreach? I need to grab each ID and then use those IDs in continuing PHP after. Here is what I have:

$chall_entries = get_group('challenge_entry', $post_id = 4643);
  foreach($chall_entries as $art_entry): //artisan challenges only
    if( $art_entry['challenge_entry_challenge_type'][1] == 'Artisan' ):
      global $task_post_id;
      $task_post_id = intval($art_entry['challenge_entry_assign_task'][1]);
      echo $task_post_id; //THIS IS REPEATING THE SAME ID TWICE - WHY? 
      //HOW DO I GET EACH ID AND ITERATE THEM FROM THE MAGIC FIELDS
      //WITHOUT USING YET ANOTHER FOR EACH?
    endif;
  endforeach;

To give an idea of how the Magic Fields are set up on the dashboard, they're like this:

Custom Post Type w/ MFs
    Repeating Group of Fields (there are two groups right now)  
        Fields within each group

So if there are TWO groups which is how it is now:

Custom Post Type w/ MFs
    Group A  
        Group A Fields
    Group B  
        Group B Fields

So the problem is that Group A's field is repeating versus looping to also get Group B the second time...


CODE UPDATE #1 - 7/6/2015

Just to clarify, the goal is to loop through two separate MF groups. One group has the ID I need for the second group. That ID is a parameter needed to create the second group's loop except I need that ID to be dynamic and not hardcoded, hence the first group's PHP. Here's the code for the "second group" if it helps:

$artisan_chall_task = get_group('task_entry', $post_id=$task_post_id); //SEE THE ID HERE?
  foreach($artisan_chall_task as $art_chall_task):
    $task_ach_id = intval($art_chall_task['task_entry_achievement_id'][1]); //achievement ID
    $task_ach_link = get_the_permalink($task_ach_id); //achievement link
    echo "<tr>";  
    echo "<td class='mobile-first'>" . $art_chall_task['task_entry_task_name'][1] . "</td>";
    echo "<td class='mobile-second'>" . $art_chall_task['task_entry_task_desc'][1] . "</td>";
    echo "<td class='mobile-third'><div class='" . $art_chall_task['task_entry_task_difficulty'][1] . "-stars margin-auto'></div></td>";
    echo "<td class='mobile-fourth'><a href='" . $task_ach_link . "'>" . get_the_post_thumbnail( $task_ach_id, 'thumbnail' ) . "</a></td>";
    echo "</tr>"; 
  endforeach;

Problems I'm having so far with WebToure's Tips:

I'm getting 1 from the $length variable with var_dump, but there are two items in that array if I var_dump($art_entry['challenge_entry_assign_task']); This gives me:

      array(1) {
  [1]=&gt;
  string(4) "4644"
}
array(1) {
  [1]=&gt;
  string(4) "4652"
}

And so the for loop with $length is giving me this error:

Undefined offset: 0

I also need to pass the ID variable from the first group, outside that first group to be used as a parameter to start a second group - if not using global, how else do I do that?


CODE UPDATE #2 - 7/6/2015

I'm using the function solution from WebToure. This is in the template:

foreach($chall_entries as $art_entry): //artisan challenges only
  if( $art_entry['challenge_entry_challenge_type'][1] == 'Artisan' ):
      $task_post_id = intval($art_entry['challenge_entry_assign_task'][1]);
      //I GET MORE THAN ONE ID HERE IF I VAR_DUMP $task_post_id
  endif;
  endforeach;

  //OUT HERE THOUGH VAR_DUMP $task_post_id ONLY GIVES ME FIRST ID?
  //I WANT THE SECOND GROUP'S LOOPING HERE
  //AND EACH ID GRABBED FROM THE FIRST GROUP WITHOUT BEING IN THAT FOREACH
  print_task_entry( $task_post_id );

And this is in functions.php:

function print_task_entry( $post_id ) {
$artisan_chall_task = get_group( 'task_entry', $post_id ); // Passing the $post_id

foreach($artisan_chall_task as $art_chall_task):
    $task_ach_id = intval($art_chall_task['task_entry_achievement_id'][1]); //achievement ID
    $task_ach_link = get_the_permalink($task_ach_id); //achievement link
    echo "<tr>";  
    echo "<td class='mobile-first'>" . $art_chall_task['task_entry_task_name'][1] . "</td>";
    echo "<td class='mobile-second'>" . $art_chall_task['task_entry_task_desc'][1] . "</td>";
    echo "<td class='mobile-third'><div class='" . $art_chall_task['task_entry_task_difficulty'][1] . "-stars margin-auto'></div></td>";
    echo "<td class='mobile-fourth'><a href='" . $task_ach_link . "'>" . get_the_post_thumbnail( $task_ach_id, 'thumbnail' ) . "</a></td>";
    echo "</tr>"; 
endforeach;    

}


The Final Working Solution - 7/7/2015:

Looks like the issue was a mixture of PHP with WebToure's solution was good, and I had a modal plugin interfering. So it appeared as if all the results were printing in one modal and all at once versus each having their own modals. I just needed to ensure that each result had their own modal with a counter class made with PHP. In the end though, this was the final result (without the modal code or counter).

In Template File:

$chall_entries = get_group('challenge_entry', $post_id = 4643);
foreach($chall_entries as $art_entry): //artisan challenges only
    if( $art_entry['challenge_entry_challenge_type'][1] == 'Artisan' ):
        $task_post_id = intval($art_entry['challenge_entry_assign_task'][1]);
        print_task_entry( $task_post_id );
    endif;
endforeach;

In Functions.php:

function print_task_entry( $post_id ) {
$artisan_chall_task = get_group( 'task_entry', $post_id ); // Passing the $post_id

foreach($artisan_chall_task as $art_chall_task):
    $task_ach_id = intval($art_chall_task['task_entry_achievement_id'][1]); //achievement ID
    $task_ach_link = get_the_permalink($task_ach_id); //achievement link
    echo "<tr>";  
    echo "<td class='mobile-first'>" . $art_chall_task['task_entry_task_name'][1] . "</td>";
    echo "<td class='mobile-second'>" . $art_chall_task['task_entry_task_desc'][1] . "</td>";
    echo "<td class='mobile-third'><div class='" . $art_chall_task['task_entry_task_difficulty'][1] . "-stars margin-auto'></div></td>";
    echo "<td class='mobile-fourth'><a href='" . $task_ach_link . "'>" . get_the_post_thumbnail( $task_ach_id, 'thumbnail' ) . "</a></td>";
    echo "</tr>"; 
endforeach;    

}

Thanks WebToure! :-)

closed as off-topic by fuxia Oct 1 '16 at 4:24

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

  • intval($art_entry['challenge_entry_assign_task'][1]); I get that this line is getting only the first ID of an array of IDs, but I don't want to manually write [1], [2], [3] etc. How do I iterate through that dynamically? – RachieVee Jul 4 '15 at 7:57
  • Is the code for the "second group" in the same file? – webtoure Jul 6 '15 at 14:02
  • In the meantime, I have updated my response. – webtoure Jul 6 '15 at 14:21
  • @webtoure It's the same file. I'm trying the function solution which I think is the cleanest. It looks like inside the first group's loop, I get several IDs. But in the second group's loop that's now in a function, it'll only pull the first one. Can I exit the first loop so that way the second one from the function can exist independently of it while still grabbing the multiple IDs? I'm updating my code above again. – RachieVee Jul 6 '15 at 18:41
  • The var_dump output clearly shows a single element array. You are seeing two array(1) {... because var_dump is called every time in the loop (in this case it gets called twice). So the $art_chall_task['task_entry_achievement_id'] variable is an array with a single element (the ID you are looking for) at index 1. – webtoure Jul 6 '15 at 19:12
1
+50

Update #2: Use my first option to get all of the IDs in an array and then loop through those. I keep trying to understand how / what exactly you are trying to achieve (use the same variable to hold an ID and somehow perform an asynchronous operation below the first block of code which is for "group one"?!) and I can only come to the conclusion you have some deep misunderstandings about how PHP works.

However, I can understand that you want all of the IDs and then iterate through them in which case my first proposed option is exactly what you need.

$post_ids = array();

foreach ( $chall_entries as $art_entry ): //artisan challenges only
    if ( $art_entry['challenge_entry_challenge_type'][1] == 'Artisan' ):
        // I have NO IDEA what you mean about: 
        // "Because then Group Loop 1 will repeat for each Group Loop 1 and I don't want that to happen"
        $post_ids[] = (int)$art_entry['challenge_entry_assign_task'][1];        
    endif;
endforeach;

foreach ( $post_ids as $post_id ):
    $artisan_chall_task = get_group( 'task_entry', $post_id ); // Passing the $post_id

    foreach ( $artisan_chall_task as $art_chall_task ):
        $task_ach_id = intval($art_chall_task['task_entry_achievement_id'][1]); //achievement ID
        $task_ach_link = get_the_permalink($task_ach_id); //achievement link
        echo "<tr>";  
        echo "<td class='mobile-first'>" . $art_chall_task['task_entry_task_name'][1] . "</td>";
        echo "<td class='mobile-second'>" . $art_chall_task['task_entry_task_desc'][1] . "</td>";
        echo "<td class='mobile-third'><div class='" . $art_chall_task['task_entry_task_difficulty'][1] . "-stars margin-auto'></div></td>";
        echo "<td class='mobile-fourth'><a href='" . $task_ach_link . "'>" . get_the_post_thumbnail( $task_ach_id, 'thumbnail' ) . "</a></td>";
        echo "</tr>"; 
    endforeach;

endforeach;

Update #1:

By the looks of the posted code it seems that you are basically overwriting the global variable when going through the foreach loop instead of executing the code from the "second group" block after each pass. As I see it you have two options: to either declare an array before the "first group" code, something like $post_ids = array() and push each ID to the array in the "first group" code:

$post_ids[] = intval($art_entry['challenge_entry_assign_task'][1]);

After that is done you can then proceed with something like this:

foreach ( $post_ids as $post_id ):

    $artisan_chall_task = get_group( 'task_entry', $post_id ); // Passing the $post_id

    foreach($artisan_chall_task as $art_chall_task):
        $task_ach_id = intval($art_chall_task['task_entry_achievement_id'][1]); //achievement ID
        $task_ach_link = get_the_permalink($task_ach_id); //achievement link
        echo "<tr>";  
        echo "<td class='mobile-first'>" . $art_chall_task['task_entry_task_name'][1] . "</td>";
        echo "<td class='mobile-second'>" . $art_chall_task['task_entry_task_desc'][1] . "</td>";
        echo "<td class='mobile-third'><div class='" . $art_chall_task['task_entry_task_difficulty'][1] . "-stars margin-auto'></div></td>";
        echo "<td class='mobile-fourth'><a href='" . $task_ach_link . "'>" . get_the_post_thumbnail( $task_ach_id, 'thumbnail' ) . "</a></td>";
        echo "</tr>"; 
    endforeach;

endforeach;

The other option would be to wrap the "second group" code in a function that accepts a parameter which is the ID of a post:

function print_task_entry( $post_id ) {
    $artisan_chall_task = get_group( 'task_entry', $post_id ); // Passing the $post_id

    foreach($artisan_chall_task as $art_chall_task):
        $task_ach_id = intval($art_chall_task['task_entry_achievement_id'][1]); //achievement ID
        $task_ach_link = get_the_permalink($task_ach_id); //achievement link
        echo "<tr>";  
        echo "<td class='mobile-first'>" . $art_chall_task['task_entry_task_name'][1] . "</td>";
        echo "<td class='mobile-second'>" . $art_chall_task['task_entry_task_desc'][1] . "</td>";
        echo "<td class='mobile-third'><div class='" . $art_chall_task['task_entry_task_difficulty'][1] . "-stars margin-auto'></div></td>";
        echo "<td class='mobile-fourth'><a href='" . $task_ach_link . "'>" . get_the_post_thumbnail( $task_ach_id, 'thumbnail' ) . "</a></td>";
        echo "</tr>"; 
    endforeach;    
}

And the code for your "first group" would look like this

$chall_entries = get_group('challenge_entry', $post_id = 4643);
foreach($chall_entries as $art_entry): //artisan challenges only
    if( $art_entry['challenge_entry_challenge_type'][1] == 'Artisan' ):
        // No need for any global variable!
        $task_post_id = intval($art_entry['challenge_entry_assign_task'][1]);
        print_task_entry( $task_post_id );
    endif;
endforeach;

Original:

There are several potential issues I see with your code:

$art_entry['challenge_entry_challenge_type'][1] == 'Artisan'

Assuming you wanted the first element in the art_entry['challenge_entry_challenge_type'] array then that line should be:

$art_entry['challenge_entry_challenge_type'][0] == 'Artisan'

As you can see, the first element in an array is at index 0.

Second, don't use the global keyword: global $task_post_id;. You can in fact delete that line all together. Declaring that variable as global can lead to unpredictable behaviour unless you definitely know what you are doing. Global means that if that same combination of global and name variable is used somewhere else in the code it can be overwritten and your value could not be what you expected.

Third, the intval call can have a significant impact on your code performance during a loop so avoid that. If you really need to make sure that value is an integer you can typecast it with (int). So that line should look something like this:

$task_post_id = (int)$art_entry['challenge_entry_assign_task'][1];

Finally, it is not entirely clear to me if all of the IDs you are looking for are in this array variable: $art_entry['challenge_entry_assign_task']

If they are and are located at indexes such as $art_entry['challenge_entry_assign_task'][0], $art_entry['challenge_entry_assign_task'][1], $art_entry['challenge_entry_assign_task'][2] etc than you definitely need a looping mechanism if you want to access incrementally the value at a particular index.

I can see from a comment you've added that you do want to iterate through that array: [...] I don't want to manually write [1], [2], [3] etc. How do I iterate through that dynamically? – RachieVee 22 hours ago

In this case a classic for loop mechanism can be used:

$length = count( $art_entry['challenge_entry_assign_task'] ); // Get number of elements in array

for ( $i = 0; $i < $length; $i++ ) {
    $task_post_id = (int)$art_entry['challenge_entry_assign_task'][$i]; // Accesing the element at index $i
    echo $task_post_id;
}

I hope this helps in clearing up the situation.

  • Thanks for answering. I'm having some problems. I updated the code to hopefully better illustrate what I'm aiming for. I'm not getting anything from the $length variable with var_dump, looks like $art_entry['challenge_entry_assign_task'] on it's own doesn't provide anything. And I understand normally arrays are zero based but for some reason, MF has their field arrays starting from 1? wiki.magicfields.org/… – RachieVee Jul 6 '15 at 13:43
  • I also intended to use a global variable for the ID because the ID I pull from the first group's loop needs to used in a second group loop outside of the first. They're two separate loops but I'm passing a variable from the first loop to the second and that variable is dynamic - as in it changes hence why I needed to loop through $art_entry['challenge_entry_assign_task']. Is there a better way to pass that variable between them? – RachieVee Jul 6 '15 at 13:44
  • Actually I am getting something from $length - code updated again in a few. – RachieVee Jul 6 '15 at 13:50
  • Sorry about that- turns out your Update #1 code was good, I had a modal plugin interfering with what I perceived as content repeating but it was fine. I've put my comments in my question with the final solution. Thanks for all your patience. :-) – RachieVee Jul 7 '15 at 18:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.