I am using rules to change the author of a node. I only know the node:nid and I want to access this value using rules.

The idea is that I have a product in a shopping cart. I set the SKU to equal the Node:nid. Later when the user buys the product I collect the SKU number ( which is the same as the node:nid) and put it in a variable called $identify_node_from_sku. So I know have the node:nid saved and ready to be used.

What I need to do is identify the node:nide and change the author of that node to the current user ( the user that purchased the product)

/*
* A function to capture the sku and save it as a variable.
*/

function chris_commerce_order_contains_product_type($products) {
  global $id_nid_from_sku;  
  $id_nid_from_sku = (empty($products->sku['value']) ? 0 : $products->sku['value']); 
  return $id_nid_from_sku;
}

I need the variable $id_nid_from_sku to become the node:nid I select to be able to change the node author using rules. I want to use the rule "set a data value" to change the $node: author to the current user.

I most likely need to use the rule "fetch entity by id"
Then I should be able to select the entity fetch:author in the data field of "set a data value"

How can I make the "id" available from my variable?

Comments

Your writing is confusing.

Your writing is confusing. I'm not sure what you want. Is this it?

<?php
global $user;
$node = node_load($id_nid_from_sku);
$node->uid = $user->uid;
node_save($node);
?>

Also, as a general rule, globals should be avoided unless absolutely necessary. (The $user is absolutely necessary.) I'm not sure why you're declaring a global and also returning the same value.

Also, if the SKU is unique, you can always use EntityFieldQuery to look up the appropriate node with that SKU, so I'm not sure why you're doing this. Something like this might work:

<?php
$query
= new EntityFieldQuery();
$result = $query
 
->entityCondition('entity_type', 'node')
  ->
fieldCondition('field_SKU', 'value', $sku, '=')
  ->
execute;
if (!empty(
$result['node'])) {
 
$nids = array_keys($result['node']);
 
$nodes = node_load_multiple($nids);
}
?>

You'll have to do a little research to get the fieldCondition() call exactly right. I'm just guessing for your case.

Since you can look up a node by SKU, I don't see any cause to set the SKU to the node ID.

--
www.ztwistbooks.com. Math books that are actually fun.

Thank you for this information. The first bit of code I can understand. Using the EntityFieldQuery() I will need to research a little to understand how to use it.

Global variables - I would rather not use global variables. However, I am not sure how else to move a variable from one function to the next. I am collecting the variable in the condition and using it in the action.

1. How else could I better use the variable $id_nid_from_sku?

I am using hook_rules_condition() to determine if the product "type" is in the order. During this condition call I collect the sku number and save it in a variable. Here is the code:

/**
* Implements hook_rules_condition_info().
*/
function chris_commerce_rules_condition_info() {
  $conditions = array();

  $conditions['chris_commerce_contains_product_type'] = array(
    'label' => t('Order contains a particular product TYPE'),
     'group' => t('Chris Commerce Order'),
     'callbacks' => array(
        'execute' => 'commerce_order_rules_contains_product',
         ),
    'parameter' => array(
      'commerce_order' => array(
        'type' => 'commerce_order',
        'label' => t('Order'),
        'description' => t('The order whose line items should be checked for the specified product. If the specified order does not exist, the comparison will act as if it is against a quantity of 0.'),
      ),
      'type' => array(
        'type' => 'text',
        'label' => t('Product TYPE'),
        'description' => t('The TYPE of the product to look for on the order. This is the machine name value found in the column "type" found in the database table "commerce_product".'),
      ),
      'operator' => array(
        'type' => 'text',
        'label' => t('Operator'),
        'description' => t('The operator used with the quantity value below to compare the quantity of the specified product on the order.'),
        'default value' => '>=',
        'options list' => 'commerce_numeric_comparison_operator_options_list',
        'restriction' => 'input',
      ),
      'value' => array(
        'type' => 'text',
        'label' => t('Quantity'),
        'default value' => '1',
        'description' => t('The value to compare against the quantity of the specified product on the order.'),
      ),
    ),
  );
  return $conditions;
}
function chris_commerce_contains_product_type($products) {
  global $id_nid_from_sku;  
  $id_nid_from_sku = (empty($products->sku['value']) ? 0 : $products->sku['value']); 
}

Then I use hook_rule_action() to call the function that changes the user on that node. Here is the code you suggested. I added the input $user as the data selector needs something to put into it and it removes the global variable.

function change_node_owner_using_product_sku($user) {
  $node = node_load($id_nid_from_sku);
  $node->uid = $user->uid;
  node_save($node); 
}

My condition code does not appear to be working. The rule is not firing.
Spineless

Ah, I see the problem. You

Ah, I see the problem. You don't know how Rules callback functions work. See rules_action_execution_callback(). For starters, they can take an arbitrary number of parameters, depending on how they are defined.

See hook_rules_condition_info() and hook_rules_action_info(). They are almost exactly the same, so most of the documentation is in action_info.

In the example above, your callback is set as follows:

<?php
   
'callbacks' => array(
     
'execute' => 'commerce_order_rules_contains_product',
    ),
?>

So, you're just using the regular Commerce callback, not your special one.

Also, note that action callbacks can add inputs to a Rule execution, but condition callbacks can't.

I would recommend that you NOT modify the Commerce condition. Just use it as-is.

Or, you could take a completely different approach. How about this, instead?

Develop a custom Rules action that takes an Order data structure as an input parameter. Call it "Update product node authors" or something. The Order data structure should contain both the user ID and the list of products, right? Collect the customer user ID from that data structure, and then go through the products ordered, and update their nodes with the new uid field.

Now, just create a new rule that fires when the customer completes an order, and has your new action in it. Everything is passed to the action callback in the Order parameter, so there's no need for a global variable.

You may wish to step back even further. Why do you want to change the ownership of these product nodes?

--
www.ztwistbooks.com. Math books that are actually fun.

In fact, depending on how the

In fact, depending on how the Order data structure is set up, you may be able to get away with just adding an action to update the author of a node.

Create an action component from the Rules user interface, and use "Add loop". Add your new author update action and feed it the list of purchased product nodes and the customer user name.

--
www.ztwistbooks.com. Math books that are actually fun.

I like the idea of only using an action. The coding appears much simpler.

I was able to create the code using some snippets I found. I have one issue that appears rather odd. I cannot change the status of the order.

Here is my code.

function change_node_owner_using_product_sku($user, $node) {
  foreach (commerce_order_load_multiple(array(), array('status' => 'pending'), TRUE) as $order) {
    $product_ids = array();
    foreach (entity_metadata_wrapper('commerce_order', $order)->commerce_line_items as $delta => $line_item_wrapper) {
      if (in_array($line_item_wrapper->type->value(), commerce_product_line_item_types())) {
         $product_ids = $line_item_wrapper->commerce_product->sku->value();
         $id_nid_plus_1 =   $product_ids + 1;
         $node = node_load($id_nid_plus_1);
         $node->uid = $user->uid;
         node_save($node);
         }
     }
   }
}

In the RULE. I have two actions one that triggers the above code and the other changes the status of the order.

{ "rules_transfer_project_pages_to_owner" : {
"LABEL" : "Transfer project pages to owner",
"PLUGIN" : "reaction rule",
"TAGS" : [ "Project Creation" ],
"REQUIRES" : [ "chris_commerce", "commerce_order", "commerce_checkout" ],
"ON" : [ "commerce_checkout_complete" ],
"DO" : [
{ "change_node_owner_using_product_sku" : { "account" : [ "site:current-user" ] } },
{ "commerce_order_update_status" : { "commerce_order" : [ "commerce-order" ], "order_status" : "completed" } }
]
}
}

The order status cannot be saved as "completed". Any idea why this is not working?

Spineless

The order status cannot be

The order status cannot be saved as "completed". Any idea why this is not working?

I'm going to guess that it's because your action callback function doesn't provide a return value. See rules_action_execution_callback() again.

I'm thinking that it returns NULL, which means that Rules thinks it failed, which means that Rules won't call the next action. What happens if you change the order of the actions in your rule?

Other notes: I don't know about Commerce data structures, but I recommend that your function take a single order object as a parameter, and derive the line items and user from that (or use the global $user). Passing in $node isn't a good idea when your code derives it anyway.

Another hint: When you post here, wrap PHP code in php tags, and wrap stuff like rule exports in code tags.

--
www.ztwistbooks.com. Math books that are actually fun.

Not sure what to return?

I am returning $info int the rules_action info function.

I updated my function so I am returning the $order. However, I still cannot access the order Status. It it like there is two different "status" variables.

When I do the following:
status = 'complete',
dpm ('the status is' .$order->status)

?>

I can see the status change but when I go to the database and check the table " commerce_order" the status value has not changed.

The only way I have found to be able to change the status is to manually go to the admin/commerce/order page and manually change the status. Then the database can be changed.

How can I change the status of the order using code?

Spineless

The function you displayed

The function you displayed doesn't return anything. Is that not your callback function?

What happens when you switch the order of your actions? I.e., put in a Rules action to change the order status first? Doesn't Commerce have one of these built-in?

I'm afraid I don't know that much about Commerce. I recommend that you go over to drupalcommerce.org and ask.

--
www.ztwistbooks.com. Math books that are actually fun.

hook_cron

I need to send a mail from using hook_cron on local server.any one can help this

_

what does this have to do with this thread?

_
Don't be a Help Vampire - read and abide the forum guidelines.
If you find my assistance useful, please pay it forward to your fellow drupalers.

nobody click here