Question

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

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;  }  } }



            }   
        }
    }
Subscribe
Share

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

Thanks for the idea @ryanpq

that could work. 

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.


Submit an answer
You can type!ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

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