Call UnitConversionService in a Object preUdate hook

I’m working on project, where I need to convert values of different metric units to mm while saving the object.

Object Listner etc. works fine, can change the object key, but I struggle getting the convertion running.

Here is the code:
$depth = $object->getSpecification()->getItems()[0]->getDepth();
$convertedDepth = \Pimcore\Model\DataObject\QuantityValue\UnitConversionService::convert($depth, Unit::getByAbbreviation(‘mm’));

I get this:

Any help would be very welcome!

UnitConversionService is a… Well, service. Which means that there’s two ways you can get it into your code. If the code is container aware (i.e. if your code is in a controller), then you just need to get it like this:

$unitConversionService = $this->get('\Pimcore\Model\DataObject\QuantityValue\UnitConversionService');

If, however, it’s required by another service, such as a Listener, you need to put it in the constructor as an argument. Then your Listener should look like this:

namespace Your\Namespace\Here\EventListeners\ObjectListener;    

class ObjectListener
{
    private $unitConversionService;

    public __construct(\Pimcore\Model\DataObject\QuantityValue\UnitConversionService $unitConversionService)
    {
        $this->unitConversionService = $unitConversionService;
    }

    public function conversion(\Pimcore\Event\Model\ElementEventInterface $event)
    {
        if ($event instanceof DataObjectEvent) {
                $object = $event->getObject();
                $depth = $object->getSpecification()->getItems()[0]->getDepth();
                $convertedDepth = $this->unitConversionService->convert($depth, \Pimcore\Model\DataObject\QuantityValue\Unit::getByAbbreviation(‘mm’));
        }
    }
}

Of course, the code has largely been abbreviated, and assuming that autowiring is set to true in your services.yml file. If not, you’ll have to adjust your services.yml file a bit, that is, add the service to the arguments of your listener. For example:

object.listener:
    class: Your\Namespace\Here\EventListeners\ObjectListener
    tags:
        - { name: kernel.event_listener, event: pimcore.dataobject.postUpdate, method: conversion }
    arguments:
        - 'Pimcore\Model\DataObject\QuantityValue\UnitConversionService'

You cannot access the convert() function directly from the Service class since it’s not declared as a static function.

Hope this helps.

Also, why a preUpdate hook? You’ll only get previous data of the object. Since no change has been stored to the database yet.

Thank you very much for pointing me in the right direction, it works like a charm.

Why preUdate?
It’s good moment for renaming objects, filling not visible fields or creating related asset folder without the need to save the object twice.

Yeah, if you’re filling up your object with info that doesn’t depend on other information already stored in the object, then a preUpdate hook is the way to go.