Jump to content
Andi

[SOLVED] Find all $page->images that do NOT have the given tag(s)

Recommended Posts

Continuing my journey into PW hooks, I'm trying to find a way to retrieve all images from a page that explicitly *do not* have a certain tag (or tags) attached to them.

Found this post from 2015

But I'm wondering if there's a more elegant way to go about this.

Let's say I have a multi-image field called "images_header" and instead of

$page->images_header->findTag('mytag');

I would like to do this:

$page->images_header->excludeTag('mytag');

So I'd be able to do

// find images that don't have the tag "mytag"
$images = $page->images_header->excludeTag('mytag');
// check if there's any images
if (count($images)>0) {
	// do something..
}

Would this be possible by hooking into Pagefiles somehow?

There's this bit in /wire/core/Pagefiles.php Line 626 that I'd basically just need to reverse (or at least in my mind 😄 )

public function findTag($tag) {
	$items = $this->makeNew();		
	foreach($this as $pagefile) {
		if($pagefile->hasTag($tag)) $items->add($pagefile);
	}
	return $items; 
}

Any ideas on how this could be done in a graceful manner?

Thanks in advance!

Share this post


Link to post
Share on other sites

How to add a new method with a hook.

So if you take your that code from Pagefiles->findTag():

/**
 * Return all Pagefile objects that do NOT have the given tag(s).
 * 
 * Given tag may be any of the following:
 * 
 * - `foo` (single tag): Will return all Pagefile objects not having the specified tag.
 * - `foo|bar|baz` (multiple OR tags): Will return Pagefile objects having not having ANY of the tags listed.
 * - `foo,bar,baz` (multiple AND tags): Will return Pagefile objects having NONE of the tags listed.
 * - `['foo','bar','baz']` (multiple AND tags array): Same as above but can be specified as an array.
 *
 * @param string|array $tag
 * @return Pagefiles New Pagefiles array with items that didn't match the given tag(s).
 * @see Pagefiles::getTag(), Pagefile::hasTag(), Pagefile::tags()
 *
 */
wire()->addHook('Pagefiles::excludeTag', function (HookEvent $event) {                
	$pagefiles = $event->object; //the Pagefiles object. For every instance of $this from the original code we will use $pagefiles instead.
	$tag = $event->arguments(0); //the argument passed to the method. so it will be e.g. $images->excludeTag($tag)

	$items = $pagefiles->makeNew();
	foreach($pagefiles as $pagefile) {
		if(!$pagefile->hasTag($tag)) //the only real change is introducing this exclamation mark to negate the condition
			$items->add($pagefile);
	}
    
	$event->return = $items;
});

Now because we just negate the result of $pagefile->hasTag(), we need to be aware of the inverted logic. If you pass multiple tags it should act the way I described in the comment above, which is just Ryan's comment inverted. So if you pass 'foo,bar,baz', you may still get images tagged as 'foo'.

(i haven't tested any of this. i may have done it completely wrong.)

Edit: Apologies, I did indeed do it wrong. Fixed the code above. @Andi

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Dude you're fast! 🙂

Looking great so far, nice and simple. With this in site/templates/_init.php I can do

// retrieve all images that don't have mytag1
$images = $page->images_header->excludeTag('mytag1');

// retrieve all images that don't have mytag2
$images = $page->images_header->excludeTag('mytag2');

// retrieve all images that have neither mytag1 or mytag2
$images = $page->images_header->excludeTag('mytag1|mytag2');

I'll test this further and report back. Awesome stuff @Jan Romero, much appreciated!!

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.

  • Similar Content

    • By horst
      Hi, on a site I want to disable access to original images and only allow to access thumbnails and watermarked image variations.
      EDIT:
      A good solution for protecting original images can be found a bit down in this thread:
       
      Old content of this initial post:
       
    • By Guy Incognito
      I seem to be running into a repeated fatal error in a fresh PW install version 3.0.148. I can't quite put my finger on the pattern but it seems to be around deleting image fields or removing images from certain image fields.
      This is the trace from the log generated by trying to save a page and delete an image from an image field:
      Fatal Error: Uncaught Error: Cannot access protected property Pageimage::$original in /wire/core/PageimageVariations.php:256 Stack trace: 1. /wire/core/Pageimage.php(1327): PageimageVariations->getInfo() 2. /wire/core/Wire.php(386): Pageimage->___isVariation() 3. /wire/core/WireHooks.php(823): Wire->_callMethod() 4. /wire/core/Wire.php(450): WireHooks->runHooks() 5. /wire/core/Pageimage.php(1369): Wire->__call() 6. /wire/core/Pageimage.php(399): Pageimage->getOriginal() 7. /wire/core/WireData.php(333): Pageimage->get() 8. /wire/core/PageimageVariations.php(256): Pro Line 256 of /wire/core/PageimageVariations.php Earlier in the day I was experimenting with custom fields for images for the first time and kept running into this error, thinking it was me using this feature wrong and not having time to read up I deleted the custom image fields template and went about my business. So now I don't know if I triggered an issue or whether it was never related to the custom image fields in the first place?
      Any ideas?
    • By humanafterall
      I'm using some Custom fields for images: 
      https://processwire.com/blog/posts/pw-3.0.142/#custom-fields-for-files-images

      When I save the page, and return the fields are blank. When I re-add the text to the fields and save again then the fields save as expected.

      I know this is stated as being quite experimental but it's super useful feature I'd love to get working correctly.
      I have fields that are CKEditor fields but have overidden this on the image specific template. I've also tried it with regular text fields and I get the same bug.
      (currently using Processwire 3.0.155)
      **UPDATE**
      I've found this issue is specific to editing on pages using the PageTable fieldtype. The fields are not saving when I save the page in the PageTable.
    • By Robin S
      Displays image tags overlaid on the thumbnail using customisable colours. This makes it easier to see which images have which tags without needing to open the edit pane for individual images or changing to the list view.
      Screenshot

      Usage
      Enable tags for one or more image fields. Install the Image Thumbnail Tags module. Optionally configure colours for any of your tags.
       
      https://github.com/Toutouwai/ImageThumbnailTags
      https://modules.processwire.com/modules/image-thumbnail-tags/
×
×
  • Create New...