Node conversion?

Posts: 33
Joined: 08/25/2007

I have what I believe might be a unique situation but hopefully someone has done something like this before. I have a situation where I need to convert an "ordinary" node into a product. Actually, it's an advpoll node, but that's sort of irrelevant. The converted node needs to retain all of the comments, graphics, ownership, etc., advpoll specific information regarding votes, choices, etc., but, be changed from type advpoll to type product for the correct inclusion of pricing, attributes, etc.

Let me give an example: Say I make coffee mugs and I don't want to produce mugs that my viewers aren't going to buy. I create an advpoll page and let the users comment and vote on their favorite coffee mugs. When I get one that the viewers like, I now want to include it in Übercart as a product. However, I still want people to be able to see the judging process and comments that went into the decision to make this a product.

So far, I am able to get advpoll data loaded into a product node with very little hacking. In fact, I'm going to add a feature request (or write an extension) for advpoll for the sole purpose of including voting results - which is all I really want at that point - in non-advpoll nodes. The next part becomes a little tedious because I basically have to come up with an administration module to enter all the information that you'd normally enter when creating a "product" node from scratch.

So, I guess, 2 questions: 1) has anyone done anything like this before? 2) Is there any info, examples, of programatically creating a "product" node?

Mark

Posts: 163
Joined: 08/07/2007
Uber DonorBug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.Not Kulvik

This is another great example of the add-to-cart without a full product node function I have been trying to develop. What you could do create a product node and then "plug in" the necessary theme_uc_product_add_to_cart pieces. I am taking that function name off the top of my head btw... but it something like that. Anyway, several of us are now looking to get this workings and I think it would solve your situation as well.

This point is being discussed in another thread as well:

http://www.ubercart.org/forum/support/512/how_i_setup_direct_add_cart_li...

Steve

p.s. Actually a few threads have explored aspects of this:
http://www.ubercart.org/forum/support/360/possible_add_products_cart_tex...
http://www.ubercart.org/forum/support/507/thickbox_add_cart
http://www.ubercart.org/forum/support/412/inject_product_static_page

Posts: 304
Joined: 11/19/2007
Bug FinderGetting busy with the Ubercode.

Did anything ever come about from this? I'm probably going to write something to perform this node->cart item conversion in the near future, but I wanted to see if there was already some progress in this area.

Posts: 163
Joined: 08/07/2007
Uber DonorBug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.Not Kulvik

For me, this issue became moot when Ryan introduced Cart Links into ubercart. I have a product buy on every content page practically and some pages that are full catalog splash pages.

check it out and see if it will do what you need:

http://www.ubercart.org/docs/1434/cart_links_settings

Posts: 1314
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

Steve, I don't understand. How does this work if you're selling an item that's downloadable? If the node isn't a product node, wouldn't you need to plugin things such as shipping packages, weights, SKU, price, and any attributes or features? That seems to me more like what the original poster was talking about.

In my case I'm writing a custom module that pretty much does that - I'm allowing users with certain role permissions the ability to create a new node, which is not initially a product (just a content node) and then when they submit it, I'm hooking into uc_product_insert to add the node's data to the products table. I, of course, have to load the other values such as SKU, etc., but those are generated dynamically when the node is created.

The reason being I don't want to give the user permission to monkey with our actual product creation system (and expose our Attributes and File Downloads features to people who don't need to see that stuff)... they are just creating a node like they would a book page or a blog, but this one happens to be a node that contains other product information which can be used in reporting and other store-related stuff.

Does this make sense or am I confusing something? (Sorry, it's early Smiling)

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 304
Joined: 11/19/2007
Bug FinderGetting busy with the Ubercode.

Torgos, I think I'm probably going to go the route that you took and create something custom for my needs. I was trying to do something general in order to make a contrib module, but I think the uses for something like this are going to be fairly unique. My main problem in trying to create a generic mapping of any content type to any product type was pulling out the meta data in a way which gave me all the important fields that you'd want to map (like attributes) while leaving out all the fields that you wouldn't want to map (like nid). The goal here basically being on the fly product creation and purchasing. I got the sense that Steve was doing something more along the lines of adding an existing product to a cart from non-product nodes.

Posts: 163
Joined: 08/07/2007
Uber DonorBug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.Not Kulvik

Maybe I misunderstood? As I read the first post we basically have a situation where a community will collaboratively define the product. i.e. this mug is cool, this other one isn't. and all that content eventually leads to a phycial product, a cool mug, which would be a naode of type, product and could be placed in the cart by embedding cartlinks within the content pages that helped to define it originally.

That was the scenario I was reacting to. In the downloaded file case, I need to give it some more thought.

Posts: 1314
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

cYu wrote:
I got the sense that Steve was doing something more along the lines of adding an existing product to a cart from non-product nodes.

That's my guess, but I'm trying to think - of course I don't know the Uber API that well ... but what are the drawbacks of doing it that way, using a Cart Link, versus creating a "pseudo Product" with uc_product_insert or drupal_clone (although I have even less experience with the Drupal API)? My main hesitation is that the product node type has some specific parameters that need to get passed in order to maintain functionality of the store. Am I correct on this? I keep coming back to things like, SKU, shipping, attributes, etc etc. Of course you might not ALWAYS need these things when dealing with certain purchasable nodes, but my guess is it's probably wise to keep everything as consistent as possible.

Another idea would be, instead of duplicating work for everything, create a pseudo-temp product at the time the item is added to the cart, or when the order is submitted? Then again that'd probably fill up the database quickly. I'm thinking a temp_products table to keep track of node<->product relationships, and a new systems value for a temp_product_id or something along those lines. Scattershot as always and I'd have to examine the dis/advantages of each method.

It's hard because our needs right now are so custom that it's harder to make a module to do something like this, at least for now. Once I've gotten some of it completely locked in I might revisit it to make a more flexible Contrib.

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 163
Joined: 08/07/2007
Uber DonorBug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.Not Kulvik

TorgosPizza,

This is really off the top of my head stuff, but maybe what you want to do is use the standard product to describe your files and allow the user cart experience to be the same as if the product was shippable. Doing this would make worries about supporting SKU's etc moot. Then in the order_confirmation process you extend the customer confirmation template with a call to a routine that builds links to the files and delivers these links to the customer via the customer purchase confirmation template?

The links could be to a file delivery mechanism that deals with limiting the number of times the link is usable, etc. However the distribution of the file is managed, you are past the sale at that point and it is no longer a cart/inventory issue.

Am I anywhere in your ballpark?

Steve

Posts: 1314
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

Blessed_Steve wrote:
For me, this issue became moot when Ryan introduced Cart Links into ubercart. I have a product buy on every content page practically and some pages that are full catalog splash pages.

check it out and see if it will do what you need:

http://www.ubercart.org/docs/1434/cart_links_settings

I've decided to go this route, but dawned on my fairly quickly that you can't add a Cart Link to just any node. The node has to be a product, otherwise you get "{Name} is not a product. Unable to add to cart." Is there an easy way around this, or should I just include a call to uc_product_insert() during the node creation?

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 33
Joined: 08/25/2007

I'll have to look at the cart links. I can't envision how that would work right now but let me look at the links you put out there.

Posts: 33
Joined: 08/25/2007

Blessed_Steve wrote:
For me, this issue became moot when Ryan introduced Cart Links into ubercart. I have a product buy on every content page practically and some pages that are full catalog splash pages.

check it out and see if it will do what you need:

http://www.ubercart.org/docs/1434/cart_links_settings

OK - just looked at that and that's not going to work. It assumes the existence of a product already. Allowing a quick link to an existing product is not the issue. It's converting an advpoll node into the product node to CREATE the product that you would then link to. In other words, I'm looking for an "automated" way to create product nodes.

Posts: 1314
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

It would almost require a Contrib, something "similar" to what I was working on but different. I'm thinking a submit button within the Node Edit screen that says "Convert to Ubercart Product" or something, and that would trigger the Contrib's function which invokes uc_product_insert (I think that's right) which would be similar to cloning a View. Then you can fill out the product-specific things like Shipping, SKU, etc., and save it. That way you'd be keeping the nid the same but now there'd be a row in the products table to associate it, as well as to allow hooking into hook_node_info() (hook_product_info).

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 33
Joined: 08/25/2007

torgosPizza wrote:
It would almost require a Contrib, something "similar" to what I was working on but different. I'm thinking a submit button within the Node Edit screen that says "Convert to Ubercart Product" or something, and that would trigger the Contrib's function which invokes uc_product_insert (I think that's right) which would be similar to cloning a View. Then you can fill out the product-specific things like Shipping, SKU, etc., and save it. That way you'd be keeping the nid the same but now there'd be a row in the products table to associate it, as well as to allow hooking into hook_node_info() (hook_product_info).

Ah... exactly the tidbits of information I was looking for Smiling Thank you very much.

Posts: 1314
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

Sounds good in theory, doesn't it? If you get it working, let me know. Would like to help test it... and I know there was quite a bit of requesting for this type of feature, so hats off to you if you can work it out!

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 33
Joined: 08/25/2007

Yeah, I agree. It sounds good... But now that I've dug into it a little bit, it looks like I can accomplish two of my objectives with one mod if I can get it working:

1) Convert an existing node of type X into a node of type Product
2) Create a node of type Product programatically (is that really even a word?)

Unless I'm missing something, it appears all you really have to do is imitate the functionality of /node/add/product. The lion's share of that is in one call in uc_product, and it looks like most of the rest of it are hooked in via different node_api hooks here and there. However, the image attachment has me completely stymied. Any idea where that particular piece of code is? My initial thought was a hook in the image module or image_attach, but I can't seem to find it.

Posts: 33
Joined: 08/25/2007

I don't know if this is what everyone else is looking for, but it works quite nicely for me.

<?php
function ecosubmit_node_to_prod($did,$rev){
 
$nid = db_fetch_object(db_query("SELECT n.nid,r.path_design FROM {et_designs} n RIGHT JOIN {et_designs_rev} r ON n.did=r.did WHERE r.did=%d AND r.rev=%d",$did,$rev));

 
// Load our design node to get the relevant information for the graphics
 
$node = node_load($nid->nid);

 
/* Need to fill out enough of these things to make this work
  $node->vid            : exists
  $node->nid            : exists
  $node->model          : This is the SKU.  Needs to be autogenerated.  Based on what?
  $node->list_price     : What should this be? The actual sell price?
  $node->cost           : This is our cost.  Total swag here.
  $node->sell_price     : This will have to be determined
  $node->weight         : Ditto
  $node->weight_units   : lb
  $node->length         : Unless we're calculating shipping this is immaterial.  I would assume
                        : shipping would be the same regardless
  $node->width          : Ditto
  $node->height         : Ditto
  $node->length_units   : in
  $node->pkg_qty        : 1
  $node->default_qty    : 1
  $node->unique_hash    : Need to figure out how this is generated.
  $node->ordering       : Have no clue what this means
  $node->shippable      : Yes?

  We also have to add the image, choose a catalog, set the fact that we're tracking stock levels,
  set original inventory levels, set shipping rate, package type, weight/price/shipping adjustments, etc.
  */

 
$node_type = 'product';

 
$form_id = $node_type.'_node_form';

 
// We want EcoAdmin owning all product nodes
 
$ecoadmin = user_load(array('name' => 'EcoAdmin'));
 
$new_node = array('uid' => $ecoadmin->uid, 'name' => $ecoadmin->name, 'type' => $node_type);

 
$edit=array();
 
$edit['title'] = $node->title;

 
$date = time();
 
$edit['created'] = $date;
 
$edit['changed'] = $date;
 
$edit['uid'] = variable_get('et_admin_user','1');

 
$edit['status'] = 1;
 
$edit['promote'] = 0;
 
$edit['sticky'] = 0;
 
$edit['vid'] = NULL;
 
$edit['nid'] = NULL;

 
// Ugly hack follows.  There's GOT to be an easier way to find the install path
 
$real_file = stristr($nid->path_design,'/files');
 
$file_temp = file_get_contents($nid->path_design);
 
$root = substr($nid->path_design,0,strpos($nid->path_design, file_directory_path())-strlen($nid->path_design));

 
$file_temp = file_save_data($file_temp,$root.file_directory_path() . '/imagecache/product/files/' . basename($nid->path_design), FILE_EXISTS_RENAME);

 
// For now, SKU = 'TT_' plus our node number.
 
$edit['model'] = 'TT_' . $nid->nid;

 
// Fill in some random crap for now.  These should be set as variables or even their own table
  // with defaults for the products
 
$edit['list_price'] = 0;
 
$edit['cost'] = 10;
 
$edit['sell_price'] = 15;
 
$edit['weight'] = 1;
 
$edit['weight_units'] = 'lb';
 
$edit['length'] = 9;
 
$edit['width'] = 6;
 
$edit['height'] = 3;
 
$edit['length_units'] = 'in';
 
$edit['pkg_qty'] = 1;
 
$edit['default_qty'] = 1;
 
$edit['ordering'] = 0;
 
$edit['shippable'] = 1;

 
// Are these two necessary?  I think not, but haven't tested.
 
$edit['op'] = 'submit';
 
$edit['submit'] = 'submit';

 
$url = drupal_execute($form_id,$edit,$new_node);

 
// grab our nid
 
$new = explode('/',$url);
 
$new_node = node_load($new[1]);

 
// In theory, all of the below should be able to be done with the above drupal_execute, but my
  // forehead is tired from all the wall banging trying to figure out how.

  // These two necessary?
 
$new_node->field_image_cache_upload = '';
 
$new_node->upload = '';

 
// This field name comes from the CCK imagecache set up
 
$new_node->field_image_cache = array(
    array(
     
'flags' => array(
         
'delete' => 0,
        ),
     
'alt' => basename($file_temp),
     
'title' => basename($file_temp),
     
'filename' => basename($file_temp),
     
'filepath' => $file_temp,
     
'filemime' => 'image/jpeg',
     
'filesize' => filesize($file_temp),
     
'fid' => 'upload',
    ),
  );
 
node_save($new_node);

}
?>

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

Maybe base_path() is what you're looking for?

The unique_hash is the result of md5() with a concatenation of most of the product's fields and the result of time() given as the parameter. It's just a semi-reliable way to get a unique id for your products.

Posts: 21
Joined: 05/27/2008

Hello,

I'm actually interested in adding a "price" to an existing item, whether it be a movie with all kinds of custom cck fields, or something else. I just wish to be able to add it to the Cart for checkout by passing my existing node id (of type "movie") and a price.

Your function looks like it could work for what I'm trying to do but I'm wondering if there's something simpler.

I don't want to have to create a separate "product" type for every custom node type I'm using, but I suppose I could just make a node-reference to the "product" that's in the back end for the actual item I'm trying to sell.

Thanks Smiling

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

If they're custom node types, you can turn them into products by creating a product class of the same name. All of the CCK fields and other customizations will remain, but the product module will add its functionality to it.

Posts: 21
Joined: 05/27/2008

Lyle wrote:
If they're custom node types, you can turn them into products by creating a product class of the same name. All of the CCK fields and other customizations will remain, but the product module will add its functionality to it.

I'm not exactly sure I understand how to create a "product class" =x

Posts: 2267
Joined: 08/07/2007
AdministratoreLiTe!
Posts: 21
Joined: 05/27/2008

Lyle wrote:
This page should help: http://www.ubercart.org/docs/user/3341/understanding_product_classes

Thanks Smiling This is exactly what I was looking for.