<?php
/*
* The software is distributed under the enclosed dual licence agreement. Accordingly, it is the responsibility of the licensee to use the software under the terms of the GPLv3 or, if purchased, under the terms of the commercial licence. Simultaneous use of the software under both licence forms for the same licensed object or a subsequent ‘change’ of licence forms by the same licensee is not permitted.
*
* In accordance with the provisions of the respective licences, it is only possible to
* a.) use Blackbit software under GPLv3 with the Pimcore Community Edition under GPLv3 or
* b.) combine Blackbit software under a commercial licence and Pimcore under a commercial licence.
*
* You can use the software under the terms of the GNU General Public Licence, Version 3 (GPLv3). This brings with it many rights of use and freedoms:
* Open source - You can view the unencrypted programme code of our software.
* Customisation - You can adapt the software to your needs and develop it further as you wish.
* Distribution - You can copy, distribute and even sell the software or further developments of the software as long as you comply with the GNU GPL v3 licence. Because you become the owner of the code when you purchase the bundle, there is no warranty and no free service.
*
* Alternatively, you can use the software under the Blackbit Commercial Licence. This means that the software remains the property of Blackbit and may be used in one instance per licence. Blackbit grants the user a limited right of use and eliminates defects and errors and provides updates free of charge during the contract period. Optionally, separate service and support contracts can be concluded for Blackbit software.
*
* For further information, please refer to the respective licence files or contact sales@blackbit.de
*/
namespace Blackbit\DataDirectorBundle\EventListener;
use Blackbit\DataDirectorBundle\Command\CheckAutomaticImportCommand;
use Blackbit\DataDirectorBundle\Controller\ImportController;
use Blackbit\DataDirectorBundle\lib\Pim\Helper;
use Blackbit\DataDirectorBundle\lib\Pim\Import\CallbackFunction;
use Blackbit\DataDirectorBundle\lib\Pim\Item\ImporterInterface;
use Blackbit\DataDirectorBundle\lib\Pim\Item\ItemMoldBuilder;
use Blackbit\DataDirectorBundle\lib\Pim\RawData\Importer;
use Blackbit\DataDirectorBundle\lib\Pim\Serializer;
use Blackbit\DataDirectorBundle\model\Dataport;
use Blackbit\DataDirectorBundle\model\DataportResource;
use Blackbit\DataDirectorBundle\model\Fieldmapping;
use Blackbit\DataDirectorBundle\model\ImportStatus;
use Blackbit\DataDirectorBundle\model\PimcoreDbRepository;
use Blackbit\DataDirectorBundle\model\Queue;
use Blackbit\DataDirectorBundle\model\RawItem;
use Blackbit\DataDirectorBundle\model\RawItemData;
use Blackbit\DataDirectorBundle\Tools\Installer;
use InvalidArgumentException;
use Pimcore\Db;
use Pimcore\Event\Model\AssetEvent;
use Pimcore\Event\Model\ElementEventInterface;
use Pimcore\Logger;
use Pimcore\Model\AbstractModel;
use Pimcore\Model\Asset;
use Pimcore\Model\DataObject\AbstractObject;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Model\Element\DirtyIndicatorInterface;
use Pimcore\Model\Element\ElementInterface;
use Pimcore\Model\Element\Service;
use Pimcore\Model\User;
use Pimcore\Model\Version;
use Pimcore\Tool;
use Blackbit\DataDirectorBundle\lib\Pim\Cli;
use Blackbit\DataDirectorBundle\lib\Pim\Logger\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\HttpFoundation\Request;
class AutomaticImportListener implements LoggerAwareInterface
{
use LoggerAwareTrait;
private static $processCommandRegistered = [];
private static $dataports = null;
private static $currentlyInProcess = [];
/** @var ItemMoldBuilder */
private $itemMoldBuilder;
public function __construct(ItemMoldBuilder $itemMoldBuilder)
{
$this->itemMoldBuilder = $itemMoldBuilder;
}
private static function getDataports() {
if(self::$dataports === null) {
self::$dataports = Dataport::getInstance()->find([], 'name');
}
return self::$dataports;
}
public function startImports(ElementEventInterface $e) {
try {
if ($e->getArgument('saveVersionOnly') && $e->getArgument('isAutoSave')) {
return;
}
} catch (\InvalidArgumentException $exception) {
}
$object = $e->getElement();
if(!$object instanceof ElementInterface) {
return;
}
if(isset(self::$currentlyInProcess[$object->getId()])) {
return;
}
self::$currentlyInProcess[$object->getId()] = true;
$user = Helper::getUser();
$savedDraftVersion = false;
try {
if ($e->getArgument('saveVersionOnly')) {
$savedDraftVersion = true;
}
} catch (\InvalidArgumentException $exception) {
}
if($user->getId() == 0) {
$objectIsLocked = true;
} else {
$objectIsLocked = (bool)PimcoreDbRepository::getInstance()->findOneInSql('SELECT 1 FROM edit_lock WHERE cid=? AND ctype=? AND userId=?', [$object->getId(), Service::getElementType($object), 0]);
}
if($objectIsLocked) {
if(count(CheckAutomaticImportCommand::getAutomaticDirectDataports()) > 0 || count(CheckAutomaticImportCommand::getQueueableAutomaticDataports()) > 0) {
PimcoreDbRepository::retry(static function () use ($object, $user, $savedDraftVersion) {
Queue::getInstance()->create([
'command' => 'data-director:start-automatic-dataports '.$object->getId().' '.Service::getElementType($object).' --direct --user='.$user->getId().($savedDraftVersion ? ' --draft-version' : ''),
'triggered_by' => $object->getRealFullPath().' got saved'.(($user instanceof User) ? ' by '.$user->getUsername() : ''),
'worker_id' => 'check_automatic_run'
]);
});
}
} else {
foreach (CheckAutomaticImportCommand::getAutomaticDirectDataports() as $dataport) {
$commands = CheckAutomaticImportCommand::getJobsToQueue($dataport, $object, $user, new NullOutput(), $savedDraftVersion ? ['draft-version' => true] : []);
foreach (array_column($commands, 'command') as $command) {
Cli::exec($command);
}
}
if (count(CheckAutomaticImportCommand::getQueueableAutomaticDataports()) > 0) {
PimcoreDbRepository::retry(static function () use ($object, $user, $savedDraftVersion) {
Queue::getInstance()->create([
'command' => 'data-director:start-automatic-dataports '.$object->getId().' '.Service::getElementType($object).' --user='.$user->getId().($savedDraftVersion ? ' --draft-version' : ''),
'triggered_by' => $object->getRealFullPath().' got saved'.(($user instanceof User) ? ' by '.$user->getUsername() : ''),
'worker_id' => 'check_automatic_run'
]);
});
}
}
unset(self::$currentlyInProcess[$object->getId()]);
}
public function deleteRawdata(ElementEventInterface $e)
{
if (\method_exists($e, 'getArgument')) {
try {
$saveVersionOnly = $e->getArgument('saveVersionOnly');
if ($saveVersionOnly) {
return;
}
} catch (\InvalidArgumentException $exception) {
}
}
$object = $e->getElement();
$objectType = Service::getElementType($object);
$user = Helper::getUser();
foreach (self::getDataports() as $dataport) {
$sourceConfig = $dataport['sourceconfig'];
$targetConfig = $dataport['targetconfig'];
if (!empty($sourceConfig['autoImport']) && empty($targetConfig['itemClass'])) {
$itemMold = $this->itemMoldBuilder->getItemMoldByClassId($sourceConfig['sourceClass'] ?? null);
if ($object instanceof $itemMold) {
PimcoreDbRepository::retry(static function () use ($object, $dataport, $objectType, $user) {
Queue::getInstance()->create([
'command' => 'data-director:delete-rawdata --dataport='.$dataport['id'].' --object-id='.$object->getId().' --object-type='.$objectType,
'triggered_by' => $object->getRealFullPath().' got deleted'.(($user instanceof User) ? ' by '.$user->getUsername() : ''),
'worker_id' => $dataport['id']
]);
});
}
}
}
}
}