is there a (simple) way to find all USED/SELECTED images/files on a page?
I know there is a $page->files() or $page->images() method but for the sake of “content validation” i’d like to check certain fields of the file/image (and if they are filled) but only for those files being used in any of the files blocks on the page.
I guess the “Solved” tag is there by mistake. FYI, this is how I report the images used all over my site to show their attributions. Basically, I am using this collection:
<?php
/**
* This collection will return all images, which have licenses or attributions,
* filtered by visibility for logged in / not logged in users, and without
* multiple occurances of the same image.
*/
return function ($site) {
$Pages = $site->index();
if (! kirby()->user()) {
$Pages = $Pages->filterBy('isProtected',false);
}
$allImages = $Pages->images()->filterBy('license','not in',['']);
$allImages->add($site->images());
$uniqueImages = new Kirby\Cms\Files;
$hashTable = [];
foreach ($allImages as $image) {
$md5 = md5_file($image->root());
if (isset($hashTable[$md5])) { continue; }
$hashTable[$md5] = 1;
$uniqueImages->add($image);
}
return $uniqueImages;
};
Do you want to do this only on a per page basis? in all page content or just the blocks field? Or check all images over the whole site?
For a single page and the images belonging to this page:
<?php
// Get all uuids of the page's images
$uuids = $page->images()->pluck('uuid', ',');
// Get the block/layouts field value and remove the slashes
$block = stripslashes($page->layout()->value());
// Create a pattern from the uuids by exploding the array
preg_match_all(
'!\(' . implode('|', $uuids) . '\)!',
$block,
$matches
);
// $matches returns an array of uuids present in the given string
dump($matches);
As each image/file being used on the published page must have credits (a field filled by the user) we have a changeStatus::before hook in place to check wether all files have the credits set. This hook works well but currently is too restrictive as it also checks files “just” being uploaded to the page but essentially not being used as an e.g. image block.
My goal is to provide a method which is generic and doesn’t need to be touched whenever a new kind of block is added to the list … ideally.
So yes, i’d like to identify all files/images being selected in any kirbytext, block, files field on a page.
As we have not (yet) migrated to 3.8.2 (we us 3.7.5.1) we cannot use the UUID feature @texnixe, but definitely a noce approach.
This approach would work with the file id as well. Instead of getting the content of only the field, you could read the complete content file instead.
Something like
<?php
// Get all ids of the page's images
$uuids = $page->images()->pluck('id', ',');
// Get the block/layouts field value and remove the slashes
$raw = stripslashes(F::read($page->contentFile()));
// Create a pattern from the uuids by exploding the array
preg_match_all(
'!\(' . implode('|', $uuids) . '\)!',
$raw,
$matches
);
// $matches returns an array of uuids present in the given string
dump($matches);