biber Posted July 13, 2021 Share Posted July 13, 2021 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 More sharing options...
BillH Posted July 14, 2021 Share Posted July 14, 2021 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! 3 Link to comment Share on other sites More sharing options...
biber Posted July 14, 2021 Author Share Posted July 14, 2021 (edited) . Edited July 14, 2021 by biber worthless Link to comment Share on other sites More sharing options...
biber Posted July 14, 2021 Author Share Posted July 14, 2021 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 More sharing options...
BillH Posted July 14, 2021 Share Posted July 14, 2021 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/ 1 Link to comment Share on other sites More sharing options...
biber Posted July 14, 2021 Author Share Posted July 14, 2021 Hi BillH, thank You for the great help. Now the script runs, but unfortunately it stops after doing half of its job Link to comment Share on other sites More sharing options...
netcarver Posted July 14, 2021 Share Posted July 14, 2021 Maybe you are hitting the max execution time for your script. Check the docs for set_time_limit(), they may help. 1 Link to comment Share on other sites More sharing options...
BillH Posted July 15, 2021 Share Posted July 15, 2021 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 } } 1 Link to comment Share on other sites More sharing options...
biber Posted July 15, 2021 Author Share Posted July 15, 2021 @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 More sharing options...
netcarver Posted July 15, 2021 Share Posted July 15, 2021 Anything in the error logs? 1 Link to comment Share on other sites More sharing options...
biber Posted July 15, 2021 Author Share Posted July 15, 2021 @BillH Thanks again for your help, I will try your suggestion immediately. kind regards Günter Link to comment Share on other sites More sharing options...
biber Posted July 15, 2021 Author Share Posted July 15, 2021 1 minute ago, netcarver said: Anything in the error logs? sorry, nothing Link to comment Share on other sites More sharing options...
biber Posted July 15, 2021 Author Share Posted July 15, 2021 @BillH Sorry, but I am not very familiar with php-programming, so I didn't find the right place where to add your patch to your convert-script. Would you be so kind to post the whole script? Günter Link to comment Share on other sites More sharing options...
BillH Posted July 15, 2021 Share Posted July 15, 2021 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>"; ?> 2 Link to comment Share on other sites More sharing options...
biber Posted July 15, 2021 Author Share Posted July 15, 2021 @BillH Hi BillH, now your script does exactly what it is made for. Everything works fine, and I have learned more about PHP. Thanks a lot! 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now