The initial idea of this module was to allow custom PHP code to be associated with a product in order to adjust the price of the product. The nature of allowing an admin to enter a block of PHP code to be executed though, allows for much more elaborate and potentially dangerous operations.
Upon installation, this module will add a Custom Code field to your products. Sample uses of this code block are:
$item->price = $item->price;This will do nothing....but it goes in by default.
$item->price refers to the price before attribute adjustments.
if($item->qty > 5) {
$item->price = [cost] * 1.1;
}If more than 5 items are ordered, set the product price to a 10% mark-up of the product cost. Product tokens are exposed to this code so things like [cost], [sell_price], [weight], [weight-raw], etc. can be used.
if(date('j', time()) == '1') {
$item->price = $item->price/2;
}Half price on the first of each month.
if($item->qty > 2) {
$item->qty = 2;
}An attempt to mimic the max quantity module by setting the quantity to 2 if anything more than 2 is ordered.
There are limitless things to do here, but if you are going to get complicated with it you might as well just write a useful module. This also makes no attempt to notify the customer of any of these adjustments, so you'll need to do so in the description of the product.
v1.0 - 12/27/07 11:00am EST
-Added in some more efficient code as suggested by Ryan for querying and checking data.
-Added in an additional type of token replace for uc_cart_item which is currently being used by the Attribute Tokens module so that when used in combination with that module you can access product attributes in your custom block of code.
v1.1 - 12/27/07 12:00pm EST
-Added 'administer custom code' permission to restrict access to this field
| Attachment | Size |
|---|---|
| uc_custom_price1.1.zip | 3.63 KB |


Re: Custom Value Calculation
Sweet idea... simple module w/ many users for developers. I'd like to recommend for your consideration the following points:
<?php
// Line 22:
$code = db_result(db_query("SELECT custom_code FROM {uc_custom_price} WHERE nid = %d", $item->nid));
if (!empty($code)) {
// Line 80:
'#default_value' => !empty($node->custom_code) ? $node->custom_code : '',
?>
Re: Re: Custom Value Calculation
Thanks for the suggestions Ryan. Bah...security schmecurity...what possible harm could people do with a block of executed php code?
Regarding the token_replace(), this was my first stab at the token system. My understanding was that in order to allow someone to eval something like...
<?phpif($item->qty > 5) {
$item->price = [cost] * 1.1;
}
?>
I'd need to do the token_replace passing it the product object. Is that not how that works?
Re: Re: Re: Custom Value Calculation
I guess since it's a string, it's possible, but someone could do something silly like put in [order-billing-address]. But since it's all PHP and as you show they have to use $item->price anyways (so why not $item->cost?), it's probably best not to mix the replacement possibilities with just knowing the code. Perhaps it would be helpful to create a help page for users with access where you load up the latest created product and print out in a pre block its contents:
<?php$output = '<pre>'. print_r($product, TRUE) .'</pre>';
?>
You could drop this under the help menu for Ubercart and link to it from the product field's description text or something like the tokens do.
Then again, folks messing with PHP should be able to do that themselves.
Re: Re: Re: Re: Custom Value Calculation
Yeah, that example could use $item->cost instead and make more sense. I wanted to put in the token abilities to allow access to attributes not in the $item such as [width] and [width-raw] and such....but more because I wanted to learn a little bit about tokens for my own use. There might also be some obscure applications of using node tokens like [mod-yyyy], but that is a bit of a stretch. 95% off if the product has not been modified for more than 40 years?
The help idea and some explanation of available $item properties is a good idea, but I would also hope that anyone messing in this area knows a little about what is going on before they try to use this. I never noticed the Using tokens help screen before, but that is neat.
Re: Re: Custom Value Calculation
I'm not sure if drupal_eval() is exactly what I want. I think I need the undesirable behavior that drupal_eval prevents in order to set $item->price.
Using this wrapper also ensures that the PHP code which is evaluated can not overwrite any variables in the calling code, unlike a regular eval() call.
Negative balance
I just started learning PHP and have a Drupal site where I'm trying to setup a small Electronic Components store with Ubercart and I find this module really handy for handling quantity discounts but I was thinking of also using it for something else.
I don't want to accept orders that take the available balance negative so components are on backorder, that implies double shipments and I'm cutting part cost and shipping cost to the bone so I can't afford to double ship.
Would this be a good place also to insert code to check the quantity ordered against stock on hand and modify the quantity if necessary so on hand does not go negative. I would execute this code first then I would follow it with code that calculates discount.
I think this would be a good place but hey what do I know!
Thanks
k5nwa, I think you'd be
k5nwa,
I think you'd be better suited looking into the various stock control options available instead of trying to get this module to handle stock for you. I'm not sure you could even do it within this module, but if you could I have to imagine it would be pretty messy and not something that somebody new to PHP and Drupal would want to tackle.
You can try http://www.ubercart.org/contrib/4792 or look through the other available options at...
http://www.ubercart.org/contrib?filter0=**ALL**&filter1=22&filter2=**ALL...
Stock levels
I was thinking something very simple, it would be just a couple of lines, some if statements to compare the order quantity with available stock, and set the order quantity to the lower of the two.
But I will look at the module, there seems to be some problems with the module when you have different sub-parts derived from the original part.
Thanks
Cecil
k5nwa
Re: Custom Price Calculation
Enjoying this module very much. Very helpful for me. Thanks for the good work. .
One problem I come across: When using custom tokens with the Attributes Tokens module, I get errors. For example, if I have custom token called [Hours] (where hours represents number of hours of a service client is buying), and I write
echo [Hours];
I get,
Parse error: syntax error, unexpected ';' in /home/lushlila/public_html/drupal-5.7/sites/all/modules/uc_custom_price1.1/uc_custom_price.module(26) : eval()'d code on line 11
Using
echo [Hours].0;
makes it works fine though.
The error occurs not only with echo, but also with assignment (and probably lots of other things too).
Access to order total.
First I would like to say that this module is wonderful, I'm just started setting up a store and I setup my parts for have a discount based on quantity ordered and it's working great. I setup 4 levels of discount, the levels and discount vary with the parts and this is perfect. I have a template file with different scenarios that I copy and paste in.
I wanted to try something else, I have parts I give away for the cost of shipping and handling but I want to limit the quantity they can order based on the orders sub-total. I have instructions in the catalog to go shopping for the free parts after they have completed their carts so they get the maximum quantity of freebies.
So can I access from the module the order totals, are they conveniently in a variable somewhere?
Thanks for the assistance and making this module available.
Cecil
k5nwa
Make it more clear
To make it more clear some sample code;
$balance = uc_payment_balance($order);
if ($balance > 0) {
insert code here to insure that the qty ordered does not exceed my preset limit based on order total
if it does set the item Qty to the maximum allowed under the circumstances
}
Cecil
k5nwa
Blessed are the cracked, for they shall let the light in.
Keep trying but no go
I have tried several things the latest is below where I try to calculate the value of the cart. It's coming up with 0 I think because it doesn't allow any parts to be added. What is typically used so you can debug PHP code on a remote server? I want to single steps and see the content of variables, because right now I',m blind.
$cart_items = uc_cart_get_contents();
$cart_total = 0;
if (!empty($cart_items)) {
foreach ($cart_items as $c_item) {
$cart_total += ($c_item->price) * $c_item->qty;
}
}
$cart_credits = round($cart_total / 3);
if ($item->qty > $cart_credits) {
$item->qty = $cart_credits;
}
$item->price = $item->price;
Cecil
k5nwa
Blessed are the cracked, for they shall let the light in.
HELP!!!
I have narrowed it down some and this is the problem but I don't know the solution yet.
In the following code snippet the following happens;
$cart_items = uc_cart_get_contents(); // supposed to get all 10 cart items and copy them to $cart_items
$c_count = count($cart_items); // supposed to return 11 including the present item but returns 3 instead.
Lets say I have 10 items in my cart for $100
I then add a free item.
In the cart the item shows up in the 4th position (no rhyme or reason where it puts items, they go all over the place)
the function count shows that there are 3 items in the cart, it though the new entry is the end of the cart.
I think there is a bug in uc_cart_get_contents() it seems to stop transferring when it runs into a product that may not be completely in the cart, it doesn't see that there are more cart entries past product # 3.
Cecil
k5nwa
Blessed are the cracked, for they shall let the light in.
Re: HELP!!!
Cecil, now that you mention it I do recall having problems reliably using uc_cart_get_contents() from within a custom price field. I don't think I was getting anything when I would make that call. I'll look into it a little more and see if I can get to the root of the problem.
Extra detail
I works up to the item that is being entered, and it thinks that that entry is the end of the cart instead on continuing to check for more items.
Thanks
Re: Extra detail
Cecil, the way this module works doesn't lend itself to what you are trying to accomplish. This module will execute a code snippet as each item is being added to the cart each time the cart is loaded. So when you go to the view cart page, as each item is loaded in the cart each snippet will be run. This is why you are seeing item 4 execute it's code snippet and only show 4 items when you call uc_cart_get_contents(). If you want to see all of the cart contents and their adjusted prices you'd need to query the tables directly and then still do
<?phpforeach (module_implements('cart_item') as $module) {
if($module != 'uc_custom_price') {
$func = $module .'_cart_item';
$func('load', $item);
}
}
?>
...since that is how a module like uc_attributes affects the price, and then loop through the items and get a total price. This is a bad idea though and I'm not even sure it would work anyhow.
Extra detail
I will play with that code tonight your little loop is loading $items with the data from the cart, then I can do my thing? Since $item is the variable containing the current cart item, I should use another variable to hold the copy of the entire cart?
I will try it tonight. I'm a little perplexed by a Ubercart behavior, if I go to a different PC, and then look at my cart the items are in different order, should they no be in the same order, it's stored in the database and should it not pull it out the same way every time?
Thanks
Cecil
k5nwa
Blessed are the cracked, for they shall let the light in.
Re: Extra detail
You'll need to grab the items in the cart first via a direct query (which isn't a great idea), then run that code snippet so that you module_invoke modules like the attribute module to get the correct price for each item.
Lost in space!
Now you lost me "grab the items in the cart first via a direct query".
Another idea I considered was using workflow-ng event to trigger after the cart was updated and run custom code for the action, but there isn't any way to detect that event, I can trigger on going to checkout but it's a little late then.
I'll think about it (within my limits of knowledge which is minuscule at this point) and see if triggering a workflow-ng event and setting it to execute custom PHP code can be made to be triggered at the right place. But the whole thing boils down to, that when the customer enters too large a quantity of free items I want them to see the correction, before going to checkout but that may not be possible at present.
Cecil
k5nwa
Blessed are the cracked, for they shall let the light in.