0

I have a website, where users can add their products. After a user purchases a product and pays for it, I want to create some custom logic. I need to know the authors of the individual items purchased. After following this guide I have the below EventSubscriber code

public function orderCompleteHandler(WorkflowTransitionEvent $event) {
  $order = $event->getEntity();
  $items = $order->getItems();

  foreach($items as $item){
    error_log($item->getTotalPrice()->getNumber());
    // Here I want to get the item's author 
  }
}

(Please disregard the error_log function as it is only for developing purposes)

It works as expected and lists the prices (one-by-one) of the items purchased. Now I want to list the authors of the items as well. Unfortunately there is no built in method to get the authors. I was thinking to go in the direction of getting the order item as an entity and then getting the entity author that way. Any suggestions how to do this? or any other suggested approaches?

6
  • I haven't worked with commerce, but as an educated guess I'd say try $item->getOwner()
    – Jaypan
    Mar 7, 2023 at 14:39
  • @Jaypan Thank you for the reply. Unfortunately it doesnt work as it is a CommerceOrderItem. I get the error: "Error: Call to undefined method Drupal\\commerce_order\\Entity\\OrderItem::getOwner()"
    – ventura
    Mar 7, 2023 at 14:44
  • I just took a glance the code for OrderItem, and it doesn't appear to implement EntityOwnerInterface which means they don't store the owner of the product by default. I think you'd need a custom solution - either extend the backend class with a custom one, and implement this interface, or add an entity reference to products for users, and save the owner to that entity when commerce items are created. I don't see that you can do it with the default setup. Although you may be able to find a module that provides this functionality.
    – Jaypan
    Mar 7, 2023 at 15:02
  • @Jaypan Again, grateful for your help. I had a feeling this wasn't gonna be easy. I'm quite new to this still, but I'm trying to figure my way. One thing that is confusing me is that I was able to create a view where I only show the logged in user the orders where the logged in user is the author of the purchased items.
    – ventura
    Mar 7, 2023 at 15:11
  • Take a look at the commerce_order_item table in the database, or maybe the commerce_order_item_data table, and see if there is a column for 'Author'. Edit: Sorry, 'owner' not 'author'.
    – Jaypan
    Mar 7, 2023 at 15:23

2 Answers 2

1

The point is, the order items (purchased entities) are not products, but product variations. You need first to get product object as the parent of a variation and then you can call the getOwner() method as suggested by @Jaypan to get user object.

You can do all this stuff by one simple line inside your loop as below

foreach($items as $item) {
    $userObj = $item->getPurchasedEntity()->getProduct()->getOwner();
}
1
  • Perfect! Just what I was looking for. Works as expected! I'm changing my ugly hacking solution ;) Thank you for this!
    – ventura
    Mar 10, 2023 at 8:29
0

As per the discussion above with @Jaypan Commerce order doesn't implement the EntityOwnerInterface so I made a pretty ugly workaround, that I'm posting, so it might help others, but please only use this if you know what you are doing.

public function orderCompleteHandler(WorkflowTransitionEvent $event) {
$order = $event->getEntity();
$items = $order->getItems();

foreach ($items as $item) {
  $item_id = $item->getPurchasedEntityId();
  $database = \Drupal::database();
  $query = $database->query("SELECT * FROM commerce_product_field_data WHERE product_id = :product_id", [
    ':product_id' => $item_id,
  ]);
  $result = $query->fetchAssoc();
  $author_id = $result['uid'];
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.