Jump to content

delete orphaned files/images from site/assets/files


interrobang

Recommended Posts

I am not sure why, but I often have a lot of orphaned images in my page assets folder. Probably due to failed uploads?

What is the best way to clean up my assets folder? No problem to loop through all my pages and find the valid files, but how do I find the orphaned ones?

Link to comment
Share on other sites

Would be nice to know where they come from. There shouldn't be any. But if you use thumbnail module they don't get deleted when deleting image. Well you can't. You may loop all pages an image fields then get an array of all along with all variations. Then delete all images not in this array. Or just delete all except the original as the variations will get created again anyway at some point.

Link to comment
Share on other sites

I sometimes end up with orphaned files as a result of doing mass imports during development. My code won't be quite right the first time around and I'll end up with extra and/or duplicated files. At least that was the case this last week. It was on a pretty large scale, so not something I wanted to clean up manually. Here's how I cleaned them out. Place this in a file in your site root called clean-files.php and then load it in your browser. 

/clean-files.php

<pre><?php
ini_set('max_execution_time', 60*5); // 5 minutes, increase as needed
include("./index.php"); 
$dir = new DirectoryIterator(wire('config')->paths->files); 

foreach($dir as $file) {
  if($file->isDot() || !$file->isDir()) continue; 
  $id = $file->getFilename();
  if(!ctype_digit("$id")) continue;  
  $page = wire('pages')->get((int) $id);
  if(!$page->id) {
    echo "Orphaned directory: " . wire('config')->urls->files . "$id/" . $file->getBasename() . "\n";
    continue; 
  }
  // determine which files are valid for the page
  $valid = array();
  foreach($page->template->fieldgroup as $field) {    
    if($field->type instanceof FieldtypeFile) {
      foreach($page->get($field->name) as $file) {
        $valid[] = $file->basename; 
        if($field->type instanceof FieldtypeImage) {
          foreach($file->getVariations() as $f) {
            $valid[] = $f->basename; 
          }
        }
      }
    }
  } 
  // now find all the files present on the page
  // identify those that are not part of our $valid array
  $d = new DirectoryIterator($page->filesManager->path); 
  foreach($d as $f) {
    if($f->isDot() || !$f->isFile()) continue; 
    if(!in_array($f->getFilename(), $valid)) {
      echo "Orphaned file: " . wire('config')->urls->files . "$id/" . $f->getBasename() . "\n";                               
      // unlink($f->getPathname()); 
    }
  }
  wire('pages')->uncache($page); // just in case we need the memory
}

When you can confirm that it has found the right files (and no false positives) uncomment the "unlink" line above to have it remove the files on the next run. 

  • Like 8
Link to comment
Share on other sites

NOTE: not working with cropped images generated by Thumbnails module, these images are always "orphaned".

There are other 3rd party modules that might store files in a page's files directory as well. So that's why that unlink() is left commented, and why this is better left as a script that you adjust according to your installation, rather than as a ready-to-run module or something. It only knows about core-managed files. 

Link to comment
Share on other sites

There are other 3rd party modules that might store files in a page's files directory as well. So that's why that unlink() is left commented, and why this is better left as a script that you adjust according to your installation, rather than as a ready-to-run module or something. It only knows about core-managed files.

Thanks Ryan, your script works great for me. I just added some lines so my thumbnails from the ThumbnailsModule are also kept:
ini_set('max_execution_time', 60 * 5); // 5 minutes, increase as needed
include("./index.php");
$dir = new DirectoryIterator(wire('config')->paths->files);

foreach ($dir as $file) {
    if ($file->isDot() || !$file->isDir()) {
        continue;
    }
    $id = $file->getFilename();
    if (!ctype_digit("$id")) {
        continue;
    }
    $page = wire('pages')->get((int) $id);
    if (!$page->id) {
        echo "Orphaned directory: " . wire('config')->urls->files . "$id/" . $file->getBasename() . "\n";
        continue;
    }
    // determine which files are valid for the page
    $valid = array();
    foreach ($page->template->fieldgroup as $field) {
        if ($field->type instanceof FieldtypeFile) {
            foreach ($page->get($field->name) as $file) {
                $valid[] = $file->basename;
                if ($field->type instanceof FieldtypeImage) {
                    foreach ($file->getVariations() as $f) {
                        $valid[] = $f->basename;
                    }
                }
                // keep thumbnails:
                if ($field->type instanceof FieldtypeCropImage) {
                    $crops = $field->getArray();
                    $crops = $crops['thumbSetting'];
                    $crops_a = explode("\n", $crops); // ie. thumbname,200,200 (name,width,height)
                    foreach ($crops_a as $crop) {
                        $crop = explode(",", $crop);
                        $prefix = wire('sanitizer')->name($crop[0]);
                        $valid[] = $prefix . "_" . $file->basename;
                    }
                }
            }
        }
    }
    // now find all the files present on the page
    // identify those that are not part of our $valid array
    $d = new DirectoryIterator($page->filesManager->path);
    foreach ($d as $f) {
        if ($f->isDot() || !$f->isFile()) {
            continue;
        }
        if (!in_array($f->getFilename(), $valid)) {
            echo "Orphaned file: " . wire('config')->urls->files . "$id/" . $f->getBasename() . "\n";
//             unlink($f->getPathname());
        }
    }
    wire('pages')->uncache($page); // just in case we need the memory
}                  
  • Like 4
Link to comment
Share on other sites

Thanks both (Ryan and interrobang)!

Just have added optional support for PiM-Variations too :)

<pre><?php

$keepThumbnails = true;
$keepPimVariations = true;    // Pageimage Manipulator Variations

ini_set('max_execution_time', 60 * 5); // 5 minutes, increase as needed
include("./index.php");

if($keepPimVariations) {
   if(!wire('modules')->isInstalled('PageImageManipulator')) {
      $keepPimVariations = false;
   } else {
      // PiM is installed, but is it a version that has method getPimVariations() (Ver 0.1.0 +)
      $a = wire('modules')->get('PageImageManipulator')->getModuleInfo();
      $actual = preg_replace('/(\d)(?=\d)/', '$1.', str_pad("{$a['version']}", 3, "0", STR_PAD_LEFT));
      $keepPimVariations = version_compare($actual, '0.1.0', '<') ? false : true;
   }
}

$dir = new DirectoryIterator(wire('config')->paths->files);
foreach ($dir as $file) {
   if ($file->isDot() || !$file->isDir()) {
      continue;
   }
   $id = $file->getFilename();
   if (!ctype_digit("$id")) {
      continue;
   }
   $page = wire('pages')->get((int) $id);
   if (!$page->id) {
      echo "Orphaned directory: " . wire('config')->urls->files . "$id/" . $file->getBasename() . "\n";
      continue;
   }
   // determine which files are valid for the page
   $valid = array();
   foreach ($page->template->fieldgroup as $field) {
      if ($field->type instanceof FieldtypeFile) {
         foreach ($page->get($field->name) as $file) {
            $valid[] = $file->basename;
            if ($field->type instanceof FieldtypeImage) {
               foreach ($file->getVariations() as $f) {
                  $valid[] = $f->basename;
               }
            }
            // keep thumbnails:
            if ($keepThumbnails && $field->type instanceof FieldtypeCropImage) {
               $crops = $field->getArray();
               $crops = $crops['thumbSetting'];
               $crops_a = explode("\n", $crops); // ie. thumbname,200,200 (name,width,height)
               foreach ($crops_a as $crop) {
                  $crop = explode(",", $crop);
                  $prefix = wire('sanitizer')->name($crop[0]);
                  $valid[] = $prefix . "_" . $file->basename;
               }
            }
            // what's about PimVariations ?
            if ($keepPimVariations) {
               if ($field->type instanceof FieldtypeImage) {
                  foreach ($file->pimLoad('x',true)->getPimVariations() as $f) {
                     $valid[] = $f->basename;
                  }
               }
            }
         }
      }
   }
   // now find all the files present on the page
   // identify those that are not part of our $valid array
   $d = new DirectoryIterator($page->filesManager->path);
   foreach ($d as $f) {
      if ($f->isDot() || !$f->isFile()) {
         continue;
      }
      if (!in_array($f->getFilename(), $valid)) {
         echo "Orphaned file: " . wire('config')->urls->files . "$id/" . $f->getBasename() . "\n";
//         #unlink($f->getPathname());
      }
   }
   wire('pages')->uncache($page); // just in case we need the memory
}

Edited by horst
  • Like 6
Link to comment
Share on other sites

  • 2 weeks later...

Thanks to Ryan, in the dev-branch we now have Pageimage::isVariation() hookable.

I have added a hook to the init() method of PiM

$this->addHook('Pageimage::isVariation', $this, 'isVariationWithPim');

and with this method all valid pimVariations of a Pageimage get collected / deleted together with the other variations of the original image:

   public function isVariationWithPim($event) {
      $variationName = basename($event->arguments[0]);
      if('pim_'!=substr($variationName,0,4) || false!==$event->return) {
         // if the result of hooked method isn't false, or if the file doesn't start with 'pim_' we leave now
         return $event->return;
      }
      // ok, imagefile starts with 'pim_', does it belong to the pageimage?
      $pageimage = $event->object;                                         // get the pageimage
      $basename = basename($pageimage->name, '.' . $pageimage->ext);       // basename of pageimage
      $re = '/^pim_.*?' . $basename . '.*?' . '\.(gif|jpg|png)' . '$/';    // regexp to identify if it's a valid pim_variation
      if(preg_match($re, $variationName)) {
         // we have a match, now return array with imageinfo 
         // (the following rows are taken from original method Pageimage::isVariation(), only regexp is modified)
         $re2 = '/^pim_.*?' . $basename . '\.' .      // pim_(prefix)_myfile.
            '(\d+)x(\d+)' .                           // 50x50
            '([pd]\d+x\d+|[a-z]{1,2})?' .             // nw or p30x40 or d30x40
            '\.(gif|jpg|jpeg|png)' .                  // .ext
            '$/';
         preg_match($re2, $variationName, $matches);
         $info = array(
            'original' => $basename . '.' . $pageimage->ext,
            'width' => $matches[1],
            'height' => $matches[2],
            'crop' => (isset($matches[3]) ? $matches[3] : '')
         );
         $event->return = $info;
         return $event->return;
      }
        return false;
   }

The next release of PiM (0.1.1) will have that. :)

  • Like 4
Link to comment
Share on other sites

  • 3 weeks later...

Hi there,

This script is very useful - thank you. I have a question though...

If you allow the image option in tinyMCE and your resulting html potentially contains direct references to the resulting duplicated images in that page's assets directory, am I right in assuming that these images would be deleted using this script in its current state?

If this is the case, I'm just wondering how tricky it might be to check found images within any textArea fields found for that particular page.  

Kind regards

Nik

Link to comment
Share on other sites

Hi NikNak,

I don't use images in tinyMCE textarea fields and I do not know how one can embedd them. But I know that this script deletes all images that are not belong to an page-images-field. I have read about to select images from the current page and from other pages in PW within the tinyMCE. This images belong to page-images-fields and don't get deleted. But if you can upload and embedd images only with the tinyMCE and these images resides under /site/assets/files/nnnn/ folders, I guess they are not known by pw and get deleted.

To clarify: where do the images reside you are talking about and how did they get there?

(sorry if I ask complicated, but I never used images with tinyMCE)

Link to comment
Share on other sites

Hi Horst

I try not to use the image function from tinyMCE either. However, it may occur from time to time.

When you click the 'image' button in tinyMCE you are asked to select an image from the image fields from your current page or an image from image fields from another page you select. If you choose an image from a different page, the image is duplicated into the assets/files folder of the current page. Each time you drag to resize the image in the wysiwyg editor, a new scaled version is saved into the pages assets/files folder for that page. So you may end up with many scaled copies of an image if you rescale the image a few times. 

So you may end up with html in the textarea like <img href="site/assets/files/(current page id)/my_scaled_image.jpg" /> 

My thought was just to see if the images found in each assets/files folder were referenced within any text area fields.

Eg - you find an image called 'my_scaled_image.jpg' that isn't known to PW, but you do a string search in each of the textarea fields for the page associated with the folder the file resides in, just to make sure it doesn't exist in the html from the wysiwyg editor.

I am a designer rather than a coder, so my skills aren't great.

Regards

Nik

Link to comment
Share on other sites

Hi Nik,

thanks to clarify. You may have a look into some existing modules that deal with images and textareas: http://modules.processwire.com/categories/photo-video/

for example the ImageInterceptor. Maybe you find code that preg_matches all imagelinks of textareafields. somas Images Manager also deals with textarea fields in some parts: https://github.com/somatonic/ImagesManager/blob/master/ImagesManagerParser.module

And if you don't get it to work, please come back here to ask for help. To enhance the script to also support images in textareas is usefull for many other users I think.

I think the new code can be go here:

// ...
   // determine which files are valid for the page
   $valid = array();
   foreach ($page->template->fieldgroup as $field) {
      if ($field->type instanceof FieldtypeTextarea) {
            // here comes the code to parse the content of textarea for images links that resides in assets/files/idOfCurrentPage/
            // all found images must be added to the array $valid!
            // ...
      }
      elseif ($field->type instanceof FieldtypeFile) {
            // here follows the existent code for files and images fields

  • Like 2
Link to comment
Share on other sites

  • 10 months later...

Hi,

I ran this script and it successfully deleted 302 images. However, many other orphaned images where not deleted.

For example, on one page I have a total number of 9 full-size images with a watermark (file names shown in blue below). Each of these images also has a cropped version acting as a thumbnail. This makes a total of 18 images, but the folder contains 77:

cementing_-_13_3in_float_collar_with_stab-in_system_013.0x100.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.390x100.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.390x125.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.390x166.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.390x83.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.585x125.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.jpg
cementing_-_13_3x17_5_centralizers_box_015.0x100.jpg
cementing_-_13_3x17_5_centralizers_box_015.390x100.jpg
cementing_-_13_3x17_5_centralizers_box_015.390x125.jpg
cementing_-_13_3x17_5_centralizers_box_015.390x166.jpg
cementing_-_13_3x17_5_centralizers_box_015.390x83.jpg
cementing_-_13_3x17_5_centralizers_box_015.585x125.jpg
cementing_-_13_3x17_5_centralizers_box_015.jpg
cementing_-_20in_stab-in_adaptor_016.0x100.jpg
cementing_-_20in_stab-in_adaptor_016.390x100.jpg
cementing_-_20in_stab-in_adaptor_016.390x125.jpg
cementing_-_20in_stab-in_adaptor_016.390x166.jpg
cementing_-_20in_stab-in_adaptor_016.390x83.jpg
cementing_-_20in_stab-in_adaptor_016.585x125.jpg
cementing_-_20in_stab-in_adaptor_016.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.0x100.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.390x100.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.390x125.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.390x166.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.390x83.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.440x295.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.jpg
cementing_-_7in_guide_shoe_019.0x100.jpg
cementing_-_7in_guide_shoe_019.390x100.jpg
cementing_-_7in_guide_shoe_019.390x125.jpg
cementing_-_7in_guide_shoe_019.390x166.jpg
cementing_-_7in_guide_shoe_019.390x83.jpg
cementing_-_7in_guide_shoe_019.jpg
cementing_-_7in_liner_wipe_plug_021.0x100.jpg
cementing_-_7in_liner_wipe_plug_021.390x100.jpg
cementing_-_7in_liner_wipe_plug_021.390x125.jpg
cementing_-_7in_liner_wipe_plug_021.390x166.jpg
cementing_-_7in_liner_wipe_plug_021.390x83.jpg
cementing_-_7in_liner_wipe_plug_021.440x295.jpg
cementing_-_7in_liner_wipe_plug_021.jpg
cementing_-_9_6in_float_collar_024.0x100.jpg
cementing_-_9_6in_float_collar_024.390x100.jpg
cementing_-_9_6in_float_collar_024.390x125.jpg
cementing_-_9_6in_float_collar_024.390x166.jpg
cementing_-_9_6in_float_collar_024.390x83.jpg
cementing_-_9_6in_float_collar_024.jpg
cementing_-_float_collar_028.0x100.jpg
cementing_-_float_collar_028.390x125.jpg
cementing_-_float_collar_028.390x166.jpg
cementing_-_float_collar_028.585x100.jpg
cementing_-_float_collar_028.585x83.jpg
cementing_-_float_collar_028.jpg
cementing_-_float_shoe_029.0x100.jpg
cementing_-_float_shoe_029.390x125.jpg
cementing_-_float_shoe_029.390x166.jpg
cementing_-_float_shoe_029.390x83.jpg
cementing_-_float_shoe_029.440x295.jpg
cementing_-_float_shoe_029.585x100.jpg
cementing_-_float_shoe_029.585x83.jpg
cementing_-_float_shoe_029.jpg
pim_watermark3_cementing_-_13_3in_float_collar_with_stab-in_system_013.jpg
pim_watermark3_cementing_-_13_3x17_5_centralizers_box_015.jpg
pim_watermark3_cementing_-_20in_stab-in_adaptor_016.jpg
pim_watermark3_cementing_-_5in_drill_pipe_wipe_plug_018.jpg
pim_watermark3_cementing_-_7in_guide_shoe_019.jpg
pim_watermark3_cementing_-_7in_liner_wipe_plug_021.jpg
pim_watermark3_cementing_-_9_6in_float_collar_024.jpg
pim_watermark3_cementing_-_float_collar_028.jpg
pim_watermark3_cementing_-_float_shoe_029.jpg

pim_watermark_cementing_-_13_3in_float_collar_with_stab-in_system_013.jpg
pim_watermark_cementing_-_13_3x17_5_centralizers_box_015.jpg
pim_watermark_cementing_-_20in_stab-in_adaptor_016.jpg
pim_watermark_cementing_-_5in_drill_pipe_wipe_plug_018.jpg
pim_watermark_cementing_-_7in_guide_shoe_019.jpg
pim_watermark_cementing_-_7in_liner_wipe_plug_021.jpg
pim_watermark_cementing_-_9_6in_float_collar_024.jpg

The large number of orphaned files resulted in an assets folder of 120MB. The problem is that my shared hosting provider does not allow uploading zip files larger than 50MB.

I went through the code, but could not find out why only some of the orphaned files were deleted.

It therefore would be great if someone could give me a hint.

I am running Processwire version 2.4.3 at the moment. I also set $keepPimVariations to false.

Cheers,

Stefan

Link to comment
Share on other sites

as far as I understand this, orphaned images are images without an original image, but I may be wrong.

There are different variations in your assets/files folder:

.0x100     // this one is (auto) created for the backend, all others are custom ones => your variations
.390x100
.390x125
.390x166
.390x83
.585x125

there are a minimum of 5 variations of each original image. These are no orphaned images because their parent image are still there.

9 x 5 = 45 valid custom variations

Do you not use / need them anymore?

Edited by horst
  • Like 1
Link to comment
Share on other sites

@horst

I also believed orphaned images to be images not used any more, even if being a variation of an image that is still in use.

I might be wrong, but to me it seems the following code prevents variations from being removed as they are all put into the $valid array:

foreach ($file->getVariations() as $f) {
     $valid[] = $f->basename;
}

I made a backup, uncommented the line

// $valid[] = $f->basename;

and ran the script again. This time 579 images were removed. However, I am not sure if I also deleted those cropped images still acting as a thumbnail. Unfortunately I won't be able to test until tomorrow.

Cheers,

Stefan

Link to comment
Share on other sites

A quick update.

Not adding image variations to the $valid array will get them removed. Although this includes variations that are still in use, these will be created again dynamically on the next page view. This is acceptable for me as I am using ProCache.

As an example of the result, here is again the folder from above:

1) AFTER running the script with $valid[] = $f-basename commented out, but BEFORE page view:

19 images:

  • 9 original size images
  • 9 auto created "0x100" images
  • 1 image I am not sure why it is there)
cementing_-_13_3in_float_collar_with_stab-in_system_013.0x100.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.jpg
cementing_-_13_3x17_5_centralizers_box_015.0x100.jpg
cementing_-_13_3x17_5_centralizers_box_015.jpg
cementing_-_20in_stab-in_adaptor_016.0x100.jpg
cementing_-_20in_stab-in_adaptor_016.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.0x100.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.440x295.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.jpg
cementing_-_7in_guide_shoe_019.0x100.jpg
cementing_-_7in_guide_shoe_019.jpg
cementing_-_7in_liner_wipe_plug_021.0x100.jpg
cementing_-_7in_liner_wipe_plug_021.jpg
cementing_-_9_6in_float_collar_024.0x100.jpg
cementing_-_9_6in_float_collar_024.jpg
cementing_-_float_collar_028.0x100.jpg
cementing_-_float_collar_028.jpg
cementing_-_float_shoe_029.0x100.jpg
cementing_-_float_shoe_029.jpg

2) AFTER running the script and AFTER a page view:

37 images:

  • 19 images from above:
  • 9 thumbnails
  • 9 PIM images with watermark
cementing_-_13_3in_float_collar_with_stab-in_system_013.0x100.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.390x166.jpg
cementing_-_13_3in_float_collar_with_stab-in_system_013.jpg
cementing_-_13_3x17_5_centralizers_box_015.0x100.jpg
cementing_-_13_3x17_5_centralizers_box_015.390x166.jpg
cementing_-_13_3x17_5_centralizers_box_015.jpg
cementing_-_20in_stab-in_adaptor_016.0x100.jpg
cementing_-_20in_stab-in_adaptor_016.390x166.jpg
cementing_-_20in_stab-in_adaptor_016.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.0x100.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.390x166.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.440x295.jpg
cementing_-_5in_drill_pipe_wipe_plug_018.jpg
cementing_-_7in_guide_shoe_019.0x100.jpg
cementing_-_7in_guide_shoe_019.390x166.jpg
cementing_-_7in_guide_shoe_019.jpg
cementing_-_7in_liner_wipe_plug_021.0x100.jpg
cementing_-_7in_liner_wipe_plug_021.390x166.jpg
cementing_-_7in_liner_wipe_plug_021.jpg
cementing_-_9_6in_float_collar_024.0x100.jpg
cementing_-_9_6in_float_collar_024.390x166.jpg
cementing_-_9_6in_float_collar_024.jpg
cementing_-_float_collar_028.0x100.jpg
cementing_-_float_collar_028.390x166.jpg
cementing_-_float_collar_028.jpg
cementing_-_float_shoe_029.0x100.jpg
cementing_-_float_shoe_029.390x166.jpg
cementing_-_float_shoe_029.jpg
pim_watermark3_cementing_-_13_3in_float_collar_with_stab-in_system_013.jpg
pim_watermark3_cementing_-_13_3x17_5_centralizers_box_015.jpg
pim_watermark3_cementing_-_20in_stab-in_adaptor_016.jpg
pim_watermark3_cementing_-_5in_drill_pipe_wipe_plug_018.jpg
pim_watermark3_cementing_-_7in_guide_shoe_019.jpg
pim_watermark3_cementing_-_7in_liner_wipe_plug_021.jpg
pim_watermark3_cementing_-_9_6in_float_collar_024.jpg
pim_watermark3_cementing_-_float_collar_028.jpg
pim_watermark3_cementing_-_float_shoe_029.jpg

Cheers,

Stefan

  • Like 2
Link to comment
Share on other sites

  • 11 months later...

It depends on what PW version and third party modules you are using.

If you only use the core imagesizer, you can use it with all the dis /-advantages mentioned above.

This lines

            if ($field->type instanceof FieldtypeImage) {
               foreach ($file->getVariations() as $f) {

fetch all valid variations that will be kept, regardless of the PW version you use.

If you use the thumbnails module, this will work too.

If you use the Pim 1 module this will work if you have $keepPimVariations enabled. With Pim 2 module, you don't need to enable $keepPimVariations, because Variations of Pim2 will be detected and kept by the core ->getVariations() method already.

If you use other third party modules that create image variations, you need to check how they name the variations. If it matches the core naming scheme with -suffixes added to the original name or -suffixes added to a variation name, it will work.

You can run the script and let the unlink() line commented the first time(s). This way you can read and check all selected filenames first, before you enable the deletion!

Link to comment
Share on other sites

  • 2 months later...

@benbyf

cleaning images orphaned from the DB

Do you mean to clean <img> tags from RTE fields where the associated images are gone for some reason? Take a look here.

Or what does "cleaning images orphaned from the DB" mean?

And making this into a module is somewhat difficult because in that module you would have to cater for all different constellations, like 3rd party modules that manipulate images, which is quite hard to anticipate for a potential module author.

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
  • Recently Browsing   0 members

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