Jump to content
bookie

Importing many images of uncertain number

Recommended Posts

Hello all,

I have been trying to figure out how best to transfer the product images we have from old website to new.

Each page has from 0 to 10 images. They can be .jpg or .png and are named consistently. Because the old site is going to remain up and this is a side project I thought I might just pull from that server every time, and first tried this:

	$affixnum = 1;
	$extension = ".jpg";
	$file = 'https://www.site.com/pictures/' . $item->itemid . "_" . $affixnum . $extension;
	$file_headers = @get_headers($file);
	if($file_headers[0] != 'HTTP/1.1 200 OK'){
		$extension = ".png"; //if no .jpg, check for .png
		$file = 'https://www.site.com/pictures/' . $item->itemid . "_" . $affixnum . $extension;
		$file_headers = @get_headers($file);
	}
	if($file_headers[0] != 'HTTP/1.1 200 OK'){
		echo "<br />";								// creates content in the div so that the description aligns correctly
	}
	while($file_headers[0] == 'HTTP/1.1 200 OK'){
		echo "<img src='" . $file . "' class='u-max-full-width'>";
		$affixnum++;
		$file = 'https://www.site.com/pictures/' . $item->itemid . "_" . $affixnum . $extension;
		$file_headers = @get_headers($file);
	} 

In this case the code is in a for loop that displays every item in a catalog with its images. This works on catalogs with a couple items, but as there are 600+ items with multiple images each for a single catalog, the server timed out when I tried it for the whole thing.

So I thought I should probably just upload all the images to the new site to prevent this.

This thread >

was very helpful but I have run into another problem.

Below is my new code:

  if(count($page->images)){
    echo "Images Present"; //debug to see what is being returned
  }
  else{
    /* get the images object array for the Page */
    $myPageImg = $page->images;
    $affixnum = 1;
    $extension = ".jpg";
    $file = 'https://www.site.com/pictures/' . $page->title . "_" . $affixnum . $extension;
    echo "Testing " . $file . "<br />";
    $file_headers = @get_headers($file);
    if($file_headers[0] != 'HTTP/1.1 200 OK'){
      $extension = ".png";
      $file = 'https://www.site.com/pictures/' . $page->title . "_" . $affixnum . $extension;
      $file_headers = @get_headers($file);
      if($file_headers[0] != 'HTTP/1.1 200 OK'){
        echo "no images returned";
      }
    }
    while($file_headers[0] == 'HTTP/1.1 200 OK'){
      $page->of(false); // output formating I don't understand but seems to be needed
      $myPageImg->add($file);
      $affixnum++;
      $file = 'https://www.site.com/pictures/' . $page->title . "_" . $affixnum . $extension;
      $file_headers = @get_headers($file);
      $page->save();
      echo $file . " added. <br />";
    } 
  }

// ... followed by the below to display

<?php
        if(count($page->get('images'))): 
          foreach($page->get('images') as $image): ?>
            <a href='<?php echo $image->url?>' data-uk-lightbox="{group:'photos'}">
              <img src="<?php echo $image->url; ?>" class='u-max-full-width'>
            </a>
          <?php endforeach; 
        else : ?>
          <br /> <!-- fills div to keep formatting if there is no image -->
        <?php endif; ?>
        </div>

In this case I put it in the individual item $page as a test. 

I didn't want the import to happen if images already were imported previously. Then I wanted to save a copy of each image into the page's folder and put it in the array.

After running this I checked the item edit page in the admin side and did not see any new images in the images field. Also, no images ended up displaying on the page even though some debugging text told me that something had been found. However, if I go into the page's assets folder the images are there, so partial success! If I load the page again another copy of the images are downloaded too, which seems to mean there is nothing actually going into the $images array?

Can someone help me get these images that were imported into the asset folder also appear in the $images array? Is this a remarkably convoluted solution for which a much simpler alternative is available?

Thanks in advance for any guidance. 

Share this post


Link to post
Share on other sites
4 hours ago, bookie said:

$page->of(false); // output formating I don't understand but seems to be needed

I agree that the concept of output formatting could be better documented - questions about it come up regularly in the forums. @ryan, it would be helpful if there was a page explaining output formatting in the "Getting started" documentation.

The key thing to take onboard is that if you are going to be setting and saving values to a page, you must set output formatting to false before you do anything relating to that setting and saving. In your case, you are getting the value of a field that you will later modify...

/* get the images object array for the Page */
$myPageImg = $page->images;

...before you have turned off output formatting for $page. If you do...

/* get the images object array for the Page */
$page->of(false);
$myPageImg = $page->images;

...then when you save $page, the changes you make to $myPageImg will be saved to the field value.

Another thing: assigning a field value to a variable like this ($myPageImg = $page->images) when you intend to later modify that field value is probably not a good idea. You can get away with it for an images field because the value of an images field is an object, and objects in PHP are assigned by reference. But the same would not be true for any field whose value is not an object, e.g. a text field. When you assign the value of a text field to a variable you are assigning by value, meaning that changes made to the variable are not simultaneously applied to the field value. To illustrate...

$page->of(false);
$images = $page->images; // $images is an object assigned by reference
$images->add('https://www.site.com/image.jpg');
$page->save(); // Changes to $images will be saved to $page->images

$page->of(false);
$headline = $page->headline; // $headline is a string assigned by value
$headline .= ' foo';
$page->save(); // Changes to $headline will NOT be saved to $page->headline

So in your case, there's really no benefit to assigning $myPageImg = $page->images near the start of your code - it just increases the chance of confusion. You'd be better to make changes to $page->images directly:

//...
$page->of(false);
while($file_headers[0] == 'HTTP/1.1 200 OK'){
	$page->images->add($file);
	$affixnum++;
	$file = 'https://www.site.com/pictures/' . $page->title . "_" . $affixnum . $extension;
	$file_headers = @get_headers($file);
	$page->save();
	echo $file . " added. <br />";
}
//...

 

  • Like 3
  • Thanks 2

Share this post


Link to post
Share on other sites

@Robin S Thank you so much for the detailed explanation. I had only a vague understanding of $page->of(false) while looking at the documentation and hadn't understood exactly what commands were affected by it.

I also wasn't entirely sure of the purpose of creating a new $pageimages array, but didn't know if it would be appropriate to add files directly to $page->images as you suggested. So it's good to know that this is something that can be done a little more directly.

I made the edits you suggested and it worked like a charm! 

A tangental question, is there danger in not "closing" the $page->of(false) command to prevent unwanted editing of a page? Should I be adding a $page->of(true) line at the end of the while loop? I expect that after I do a mass "import" I will be removing this code from the template anyway but if there is a best practices answer I'd like to learn good habits early on.

Ideally I'd like to make some sort of module to do this process, but after reading the documentation I'm still not sure I understand exactly how to utilize them. I'm optimistic about figuring it out though considering how good the documentation and how helpful the community here is.

Share this post


Link to post
Share on other sites
57 minutes ago, bookie said:

Should I be adding a $page->of(true) line at the end of the while loop?

It doesn't hurt to do this, but most of the time it's not necessary. When you change the output formatting state for a page, this only lasts for the current request. On the next request PW is going to automatically set the output formatting state depending on the context the code that's executing - to quote the docs, "By default, output formatting is turned on on the front-end of the site, and off on the back-end (admin) of the site."

So probably the only case you would need to explicitly turn output formatting on after you have turned it off is if you had some code in a template file that was setting values to $page, and then later in that template file you are also outputting $page values to the front-end. But I think that would be quite rare, because most of the time when you are using the API to set page values you'll be doing that from a script separate from any template file that's outputting to the public front-end.

  • Like 1

Share this post


Link to post
Share on other sites

At the moment the script is the first half of a template in which the second part is front-end, but I want to change that in the future. At the moment I am just commenting out the import code when I don't want to run it. This is why I'd like to move towards using some sort of module, but building that is low on the priority list by virtue of some time pressure. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...