Jump to content

How to convert content from an "image extra" field


biber
 Share

Recommended Posts

Some years ago I built a site with the help of the 'Image extra'-module. After some problems I decided to change to the modern way with a field-images-template. Now I want to copy the contents of that old Image-extra-field to my new fields. Is there a way to do that for all images at once?

Link to comment
Share on other sites

I did exactly the same thing a year or two ago.

Here's the script I used (I've simplified the selector and a couple of other things, and added one comment). The script moves the image description and the ImageExtra field 'credit' to the new 'photo_caption' and 'photo_credit' fields.

I don't know if you're familiar with running such scripts, but you simply put the script somewhere on your server and enter its URL in your browser. It might be a good idea to test with the saves commented out.

<?php

	// Amend depending on where this script file is located
    include("../index.php");

    $selectedRecords = $wire->pages->find("template=my-template");
    echo "Pages with images: " . count($selectedRecords) . "<br/>";

    $recordsProcessed = 0;
    foreach($selectedRecords as $thisRecord) {
        echo $thisRecord->title . "<br/>";
        $recordsProcessed += 1;
        if(count($thisRecord->article_images)) {
            $thisRecord->of(false);
            foreach($thisRecord->article_images as $image) {
              
                $description = $image->description;
                $credit = $image->credit;

                $image->photo_caption = $description;
                $image->photo_credit = $credit;

                $thisRecord->save('article_images');
            }
            $thisRecord->save();
        }
    }
    echo "<p>Records processed: {$recordsProcessed}</p>";
?>

This was written for a one-off task, so I did nothing to refine it, but it worked. Note that at the time both saves were necessary, though I think this has been resolved now and, depending on which version of PW you are running, you may be able just to save the whole record - but it'd probably be easier to leave it as it is!

  • Like 3
Link to comment
Share on other sites

Hi BillH,

now I added your script to one of my templates and called it with my browser. As long as I leave the saves commented out it runs as desired, but if I try to save the changes it comes up with an "Internal Server Error"

Link to comment
Share on other sites

The script should be a standalone PHP file, not placed in a template.

So, for example, you might name the script "fix-images.php" and put the file in /site/.

Then, if you normally access the site at https://www.mysite.com, run the script by accessing https://mysite.com/site/fix-images.php .

For more details, take a look at this page (particularly the last section):  https://processwire.com/docs/front-end/include/

  • Like 1
Link to comment
Share on other sites

I'd definitely try @netcarver's suggestion first.

And if that doesn't work, you could try putting this after saving the record, though I'm not sure if it will make a difference:

$pages->uncacheAll();

Then if you still have the problem, for a one-off task you could split the processing into batches. Doing something like the following is highly inefficient, but simple and will definitely work – and is probably more efficient than spending a lot of time trying to find a better fix!

$startPage = 0; // Manually change this for each batch
$endPage = 1000; // And this too
$pageCounter = 0;
foreach($pageToProcess as $thisPage) {
	$pageCounter += 1;
	if (($pageCounter >= $startPage) && ($pageCounter <= $endPage)) {
		// Process $thisPage here
	}
}

 

  • Like 1
Link to comment
Share on other sites

@netcarver

I asked my webhoster: scripts are limited at 300 seconds, but my script stops at less than 60 seconds. So I addet

	set_time_limit(300);
	ignore_user_abort(0); 

to my script, but this did not change anything.

Greetings Günter

Link to comment
Share on other sites

Here you go!

You need to decide how big each batch will be and set the $startPage and $endPage values each time you run the script. For example, if you have 1230 pages and decide to run the script three times you could use 0 and 499; 500 and 999; 1000 and 1300. Note that you should start at 0 (because the indexing of the page array starts at 0). And it's OK if the last number is larger than the total number of pages.

Note also that I haven't tested the code, so let me know if it doesn't work!

<?php

	// If you put the script in /site/ this is OK (otherwise you may need to amend)
    include("../index.php");
    
    // Change these two values for each batch
    $startPage = 0;
	$endPage = 499;
	
	// Change the selector to match your pages
    $selectedRecords = $wire->pages->find("template=my-template");
    
    echo "Pages with images: " . count($selectedRecords) . "<br/>";

	$pageCounter = 0;
    $recordsProcessed = 0;
    foreach($selectedRecords as $thisRecord) {
    
		$pageCounter += 1;
		if (($pageCounter >= $startPage) && ($pageCounter <= $endPage)) {    
    
			echo $thisRecord->title . "<br/>";
			$recordsProcessed += 1;
			if(count($thisRecord->article_images)) {
				$thisRecord->of(false);
				foreach($thisRecord->article_images as $image) {
			  
					$description = $image->description;
					$credit = $image->credit;

					$image->photo_caption = $description;
					$image->photo_credit = $credit;

					$thisRecord->save('article_images');
				}
				$thisRecord->save();
			}
		}
    }
    echo "<p>Records processed: {$recordsProcessed}</p>";
?>

 

  • Like 2
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...