Watermarking a product class?

Posts: 70
Joined: 04/14/2008

I've read the information on watermarking product images here, but seems to me this would apply watermarks to all products in your catalog. Any ideas on watermarking only specific products, perhaps through a product class?

Posts: 924
Joined: 11/05/2007
Bug FinderFAQ ModeratorGetting busy with the Ubercode.

Sure, if you wanted to watermark only one particular class, modify the theme function in that post to check for the class before you apply the watermark. If you want to get a little finer grained, add a CCK field to the product that will hold boolean to indicate whether/not that particular product image should be watermarked, then check the boolean in the theme function.

--

<tr>.

Posts: 70
Joined: 04/14/2008

I don't know much about ubercart's drupal underpinnings, athough I'm learning. Could I get some rudder on how to pull the product class in php?

Posts: 70
Joined: 04/14/2008

Am I correct in assuming that when you define a new product class, you're also creating a new node type? So, if I have a product class called "artwork", would $node->type also be "artwork"?

I did a var_dump on a product after I created a new product class "artwork" and made it an associated node in the product catalog vocabulary. I don't want separate catalogs -- one is fine, but I want two classes of products, "artwork" and everything else (default "uc_product" is fine). Artwork needs watermarks, generic products do not. When I take a look at uc_product_node_info for a generic product, though, I see that "artwork" is a key in the returned array. I'm assuming this is because I made it an associated node in the catalog vocabulary? $node->type is returning NULL, so that's obviously not the key to this puzzle.

I'm obviously exposing my ignorance here -- what precisely is a product class wrt/ all other nodes and how do I access it in PHP? Is this really the best way to skin this onion?

Gash

Posts: 2243
Joined: 08/07/2007
AdministratoreLiTe!

$node->type should never be NULL. Unless something is messing up the nodes, this shouldn't happen. How are these nodes being created?

Product classes are node types that act like products. The $node->type would be the same as the product class in that case.

Posts: 70
Joined: 04/14/2008

I create the products through the "Create content" link.

I may be trying to access those attributes incorrectly. I was playing with a product, adding different variables in php tags in the content field to try and figure out how to access the product class. uc_product_node_info returned the info delineated above, while $node itself was NULL.

Gash

Posts: 70
Joined: 04/14/2008

Just to clarify, products are showing up fine, are listed in the catalog fine, and receive node id's, etc., as I would expect them to. I simply can't figure out how to access the product class itself. If it is through $node->type (which seems to be the case), would there be a reason I can't access it from within the node itself? In other words, if I add the following to the description field in a product, would it fail for some reason (definitely not the case for uc_product_node_info(), but resulting in NULL for $node->type):

var_dump($node->type);

Again, I'm not trying to do anything programmatically here -- I just want to figure out how this all works.

Gash

Posts: 2243
Joined: 08/07/2007
AdministratoreLiTe!

OK, I understand what's going on here.

When a node's body is run through the PHP filter, it's taken out of the scope of the code that called it. This means that variables don't carry over from the module or theme code into the node body. This is why $node is NULL, it hasn't been given a value yet. Fortunately, all of Drupal's functions are available, so you can do

<?php
  $node
= node_load(34); // Use the actual node id since you can't import it from anywhere else.
?>

and get the $node->type from there.

Posts: 70
Joined: 04/14/2008

Awesome! That worked, and I got the behavior I was expecting from $node->type. The rest should be pretty easy to pull off.

Thanks for the help!

Posts: 70
Joined: 04/14/2008

Getting the patched version of image cache that allows image compositing was easy enough, but using the function (in template.php) from the tutorial here results in a multitude of parse errors. I suspect something in how the function is called, but I can see nothing obvious -- but I receive "unexpected T_STATIC" or "unexpected T_STRING" errors no matter what line I make the first line of the function. That suggests something in the line prior to it, which is the function constructor itself:

function garland_uc_product_image($images){
...
}

Has something changed in how themes are handled that could cause this function to fail?

Posts: 70
Joined: 04/14/2008

Resolved. I tracked it down to unicode gremlins introduced in my text editor (specifically on the implode('>', ..) calls). With those squashed, it's working as expected.

I'll have to fiddle w/ the function to get it to output the proper images based on the product class -- it's either watermarking everything now or not outputting product images at all. Shouldn't be too difficult.

Thanks for all the help.

Gash

Posts: 70
Joined: 04/14/2008

Lyle -- how does the node scoping extend to theme functions? I can't seem to access $node attributes from within template.php either, which seems odd to me.

If I can't access the product class via $node->type in template.php, how else might I discriminate between product classes?

I'd rather not use a CCK boolean, mostly because I'll be handing this over to a client who will not really understand how that works, and likely won't remember to do it when he adds artwork.

Thanks for your patience. I received the Drupal Pro book in the mail yesterday, so will be eradicating my ignorance soon, I hope.

Gash

Posts: 70
Joined: 04/14/2008

It would probably help if I posted my code. From template.php:

function garland_uc_product_image($images, $node){
  if ($node->type == 'artwork'){
//Apply watermark
} else {

//Apply same technique as uc_product_image from uc_product.module

}

I receive "warning: Missing argument 2 for garland_uc_product_image()" messages when the template.php file is processed, which seems to imply that either $node is not set in the scope in which garland_uc_product_image() is being called, or my function is overriding a function that doesn't require the second variable and is somehow causing a conflict? If I call it without $node, however, only my "else" statement is processed, again implying $node isn't set within the scope in which the function is called. I can't load each node dynamically, either (at least I don't think I can).

Again -- I'm certain this boils down to not understanding Drupal well enough. My apologies -- I'm learning, but I do appreciate the mentorship and guidance that's been put out here!

Gash

Posts: 70
Joined: 04/14/2008

Here's the solution Smiling

Drupal's arg() function cured my ills. Tacking the following conditional onto my theme_uc_product_image() function works like a charm:

function theme_uc_product_image($images){
       if (arg(0) == 'node' && is_numeric(arg(1))) {
           $node = node_load(arg(1));
           if ($node->type == 'artwork'){

           //Apply the watermark

           } else {

           //Don't . . .

          }
     }
}

So, my product class "artwork" receives the watermarks, while the rest of the products in the catalog don't!

Don't know if approach would work for alternative URI's, though (suspect it might not). I'll have to research that a bit more.

Gash

Posts: 70
Joined: 04/14/2008

Here's the procedure I used to watermark a product class:

  1. Install the patched imagecache.module
  2. Follow the instructions here, specifically in the "Add watermarking to full sized images" section of the tutorial
  3. Make your new product class if you haven't already. Be sure to associate it with the catalog vocabulary (administer->categories->edit vocabulary.
  4. Modify template.php for your theme to include something like the following:
  5. function YOURTHEME_uc_product_image($images){
    if (arg(0) == 'node' && is_numeric(arg(1))) {
    $node = node_load(arg(1));//array('nid' => arg(1)));
    }

    static $rel_count = 0;
        $thickbox_enabled = module_exists('thickbox');
    $first = array_shift($images);
        $output = '<div class="product_image">';
    if ($thickbox_enabled){
        if ($node->type == 'YOUR_PRODUCT_CLASS'){
    $output .= '<a href="'. check_url(file_create_url('imagecache/watermark/'. $first['filepath'])) .'" title="'. $first['title'] .'" class="thickbox" rel="thickbox'. $rel_count .'">';
        } else {
    $output .= '<a href="'. check_url(file_create_url($first['filepath'])) .'" title="'. $first['title'] .'" class="thickbox" rel="field_image_cache_'. $rel_count .'">';
    }
    }
    $output .= theme('imagecache', 'product', $first['filepath'], $first['alt'], $first['title']);
        /* if (count($images)){
            $output .= '<br />'. t('Click for more images.');
      } */
    if ($thickbox_enabled){
    $output .= '</a>';
    }
    $output .= '<br />';
    foreach ($images as $thumbnail){
        if ($thickbox_enabled){
    if ($node->type == 'YOUR_PRODUCT_CLASS'){
    $output .= '<a href="'. check_url(file_create_url('imagecache/watermark/'. $thumbnail['filepath'])) .'" title="'. $thumbnail['title'] .'" class="thickbox" rel="thickbox'. $rel_count .'">';
    } else {
    $output .= '<a href="'. check_url(file_create_url($thumbnail['filepath'])) .'" title="'. $thumbnail['title'] .'" class="thickbox" rel="field_image_cache_'. $rel_count .'">';
    }
    }
        $output .= theme('imagecache', 'thumbnail', $thumbnail['filepath'], $thumbnail['alt'], $thumbnail['title']);
        if ($thickbox_enabled){
            $output .= '</a>';
        }
    }
    $output .= '</div>';
    $rel_count++;
    return $output;
    }

And you're done! This will watermark the thickbox images for your product class when the product thumbnail is clicked. This will not watermark the thumbnails or product_list images, however (I don't need that functionality, but if you do, you can use some of the same techniques outlined here. Have a look at the code in uc_product.module for the specific bit of functionality you wish to override, and add something similar to your template.php file). Be sure to replace YOURTHEME and YOUR_PRODUCT_CLASS in the code above with the appropriate info.

Thanks for all the help in resolving this. I'm much more familiar with Drupal due in large part to help given here, and I appreciate it.

Gash