PHP Re-loop a foreach loop to sort images according to size

March 24, 2015 3.4k views
PHP WordPress Ubuntu

I have an array of images.

In the array, for each image, I have whether the image is tall or wide.

I need to loop through all of the images, and pair a tall with wide into a div, then move to the next until they are all done.

I have something that sort of works using a foreach loop, but the problem is that some images get skipped ... the loop stops when each image has gone through the loop, which is standard behavior for a "foreach" loop, from what I have read..

So now I am wondering if there is a different loop I should use, or should I put my foreach loop inside another loop so that it repeats until the images are used up?

Here is my loop so far, that does what I want, but leaves out several images:



        $num_of_images = count($images);
        $notins = array();
                $order  = 1;
        $i = 0;
                 //start my loop
         foreach ($images as $image) {
            $id = $image->ID;
                         //check if image is in the notins array..skips if it is
                          if (!in_array($id, $notins)){
                          //find out if the image is tall or wide
               $attach = wp_get_attachment_image_src(  $id, 'full');
               $height = $attach['2'];
                $width = $attach['1'];  
                 if ($height < $width) { $size = "wide" ;} else { $size = "tall" ;}
                           //get the link to the sized image
               $preview_array = image_downsize( $image->ID, $size );
               $img_preview = $preview_array[0]; // thumbnail or medium image to use for preview.




                 if( $order == 3 ){   //if previous slide was tall, get a wide slide
                    if($size == "wide") { $order = 1; array_push($notins, $id); $i++; ?>
<!-- - - - - - - - - - - Image - - - - - - - - - - - - - -->    
<div class="image <?php echo $size; ?>" style="background: url(<?php echo $img_preview; ?>) no-repeat center !important; background-size: cover !important; max-width: 100%; "> 
    </div>    
    <!-- - - - - - - - - - - end Image  - - - - - - - - - - - - - -->
</li><!--.slide --><?php

                                   }
                }  


                    if( $order == 2 ){    //if previous slide was wide, get a tall slide
                    if($size == "tall"  ) {  $order = 1; array_push($notins, $id); $i++;  ?>
<!-- - - - - - - - - - - Image - - - - - - - - - - - - - -->    
    <div class="image <?php echo $size; ?>" style="background: url(<?php echo $img_preview; ?>) no-repeat center !important; background-size: cover !important; max-width: 100%; "> 
    </div>    
    <!-- - - - - - - - - - - end Image  - - - - - - - - - - - - - -->
                        </li><!--.slide --><?php 

                                     }
                 }  




                  if( $order == 1) {   //if this is the first slide in the div
                    if( !in_array($id, $notins) ) {   $i++;  array_push($notins, $id);  ?>

<li class="the-slide gallery">
    <!-- - - - - - - - - - - Image - - - - - - - - - - - - - -->    
    <div class="image <?php echo $size; ?>" style="background: url(<?php echo $img_preview; ?>) no-repeat center !important; background-size: cover !important; max-width: 100%; ">  
</div>    
    <!-- - - - - - - - - - - end Image  - - - - - - - - - - - - - --><?php 


                             if( $i == 17 ){ ?> </div><!--.slide --> <?php  } 
                     if($size == "wide"){ $order = 2; } if($size == "tall"){  $order = 3;  }  } }



            }   
        }
    }
3 comments
  • If you want to pair one tall with one wide for each div maybe you should use your first foreach to push the elements into two arrays $tall and $wide and then loop through the larger of these two arrays grabbing one element from each array for each loop. You may have to do a bit more if one array ends up larger than the other but that would depend on how you want things to display in the end if the arrays have a non-equal number of items.

  • Thanks for the idea @ryanpq

    that could work. 
    
  • Okay, using @ryanpq idea of putting everything into two arrays has worked. I can reverse the order of using the larger or smaller of the two arrays, depending on if I want images to show up that do not have a partner image.

    Here are my loops (tested and works):

    if ($images) { 
    
                $tall = array();
                $wide = array();
                foreach ($images as $image) {
                   $id = $image->ID;                    
                   $attach = wp_get_attachment_image_src(  $id, 'full');
                   $height = $attach['2'];
                   $width = $attach['1'];  
                     if ($height < $width) { $size = "wide" ;} else { $size = "tall" ; }
                      if( $size == 'tall') {  array_push($tall, $id); } 
                      if( $size == 'wide') {  array_push($wide, $id); } 
    
                    } //get everything into two arrays
    
                //get the larger and smaller of the two arrays
                if(count($tall) > count($wide)){ 
    $large = $tall; $small = $wide; $size = "tall"; $sm_size = "wide"; 
    }  
                    else { $large = $wide; $small = $tall; $size = "wide"; $sm_size = "tall";}  
    
                //now loop through the smaller array
                 $i = 0;
                             foreach($large as $image) {
                    $id = $image;
                    $previews = image_downsize( $id, $size );
                        $img = $previews[0];  
                    $sm_id = $small[$i];
                    $sm_previews = image_downsize( $sm_id, $sm_size );
                        $sm_img = $sm_previews[0];  
    
    
    
                                                        ?>
    
    <li class="the-slide gallery">
        <!-- - - - - - - - - - - Image - - - - - - - - - - - - - -->    
        <div class="image <?php echo $size; ?>" style="background: url(<?php echo $img; ?>)
    no-repeat center !important; background-size: cover !important; max-width: 100%; ">
    </div>  
        <!-- - - - - - - - - - - end Image  - - - - - - - - - - - - - -->
        <!-- - - - - - - - - - - Image - - - - - - - - - - - - - -->    
        <div class="image <?php echo $sm_size; ?>" style="background: url(<?php echo
    $sm_img; ?>) no-repeat center !important; background-size: cover !important; max-width: 100%; ">
    </div>  
        <!-- - - - - - - - - - - end Image  - - - - - - - - - - - - - -->
    
    
    
    
                <?php $i++;  }
    
    
    
    
        } //if images
    
    

    ..

1 Answer

This question was answered by @sierracircle:

Okay, using @ryanpq idea of putting everything into two arrays has worked. I can reverse the order of using the larger or smaller of the two arrays, depending on if I want images to show up that do not have a partner image.

Here are my loops (tested and works):

if ($images) { 

          $tall = array();
          $wide = array();
          foreach ($images as $image) {
             $id = $image->ID;                    
             $attach = wp_get_attachment_image_src(  $id, 'full');
             $height = $attach['2'];
             $width = $attach['1'];  
               if ($height < $width) { $size = "wide" ;} else { $size = "tall" ; }
                if( $size == 'tall') {  array_push($tall, $id); } 
                if( $size == 'wide') {  array_push($wide, $id); } 

              } //get everything into two arrays

          //get the larger and smaller of the two arrays
          if(count($tall) > count($wide)){ 
$large = $tall; $small = $wide; $size = "tall"; $sm_size = "wide"; 
}  
              else { $large = $wide; $small = $tall; $size = "wide"; $sm_size = "tall";}  

          //now loop through the smaller array
           $i = 0;
                        foreach($large as $image) {
              $id = $image;
              $previews = image_downsize( $id, $size );
                  $img = $previews[0];  
              $sm_id = $small[$i];
              $sm_previews = image_downsize( $sm_id, $sm_size );
                  $sm_img = $sm_previews[0];  



                                                  ?>

<li class="the-slide gallery">
   <!-- - - - - - - - - - - Image - - - - - - - - - - - - - -->   
  <div class="image <?php echo $size; ?>" style="background: url(<?php echo $img; ?>)
no-repeat center !important; background-size: cover !important; max-width: 100%; ">
</div> 
   <!-- - - - - - - - - - - end Image  - - - - - - - - - - - - - -->
   <!-- - - - - - - - - - - Image - - - - - - - - - - - - - -->   
  <div class="image <?php echo $sm_size; ?>" style="background: url(<?php echo
$sm_img; ?>) no-repeat center !important; background-size: cover !important; max-width: 100%; ">
</div> 
   <!-- - - - - - - - - - - end Image  - - - - - - - - - - - - - -->




          <?php $i++;  }




  } //if images

..

View the original comment

Have another answer? Share your knowledge.