Process the observer's business logic.

@return array The processed row
@throws \Exception Is thrown, if the product with the SKU can not be loaded
764568
protected function process()
    {

        // query whether or not, we've found a new SKU => means we've found a new product
        if ($this->isLastSku($sku = $this->getValue(ColumnKeys::SKU))) {
            return;
        }

        // preserve the entity ID for the product with the passed SKU
        if ($product = $this->loadProduct($sku)) {
            $this->preLoadEntityId($product);
        } else {
            // initialize the error message
            $message = sprintf('Can\'t pre-load product with SKU %s', $sku);
            // load the subject
            $subject = $this->getSubject();
            // query whether or not debug mode has been enabled
            if ($subject->isDebugMode()) {
                $subject->getSystemLogger()->warning($subject->appendExceptionSuffix($message));
            } else {
                throw new \Exception($message);
            }
        }
    }
1000958
protected function _process()
	{
		$this->_msg( 'Adding product suggestion performance data', 0 );


		$productManager = MShop_Product_Manager_Factory::createManager( $this->_getContext() );
		$productListManager = $productManager->getSubManager( 'list' );
		$productListTypeManager = $productListManager->getSubManager( 'type' );

		$expr = array();
		$search = $productListTypeManager->createSearch();
		$expr[] = $search->compare('==', 'product.list.type.code', 'suggestion');
		$expr[] = $search->compare('==', 'product.list.type.domain', 'product');
		$search->setConditions( $search->combine( '&&', $expr ) );
		$types = $productListTypeManager->searchItems($search);

		if ( ($listTypeItem = reset($types)) === false) {
			throw new Exception('Product list type item not found');
		}

		$search = $productManager->createSearch();
		$search->setSortations( array( $search->sort( '+', 'product.id' ) ) );

		$refsearch = $productManager->createSearch();
		$refsearch->setSortations( array( $refsearch->sort( '+', 'product.id' ) ) );
		$refsearch->setSlice( 1 );

		$listItem = $productListManager->createItem();
		$listItem->setTypeId( $listTypeItem->getId() );
		$listItem->setDomain( 'product' );


		$this->_txBegin();

		$start = 0;

		do
		{
			$num = 0;

			$result = $productManager->searchItems( $search );
			$refresult = $productManager->searchItems( $refsearch );

			foreach( $result as $id => $product )
			{
				$pos = 0;
				$length = ( $num % 4 ) + 3;

				foreach( array_slice( $refresult, $num, $length, true ) as $refid => $refproduct )
				{
					$listItem->setId( null );
					$listItem->setParentId( $id );
					$listItem->setRefId( $refid );
					$listItem->setPosition( $pos++ );

					$productListManager->saveItem( $listItem, false );
				}

				$num++;
			}

			$count = count( $result );
			$start += $count;
			$search->setSlice( $start );
			$refsearch->setSlice( $start + 1 );
		}
		while( $count == $search->getSliceSize() );

		$this->_txCommit();


		$this->_status( 'done' );
	}
598808
protected function process()
    {

        // process the link type attributes
        $productLinkAttribute = $this->getProductLinkAttributeByLinkTypeCodeAndAttributeCode($this->getValue(ColumnKeys::LINK_TYPE_CODE), $this->getValue(ColumnKeys::LINK_TYPE_ATTRIBUTE_CODE));

        // try to load the product link attribute
        $this->setProductLinkAttributeId($productLinkAttribute[MemberNames::PRODUCT_LINK_ATTRIBUTE_ID]);

        // load the link attribute data type
        $dataType = $productLinkAttribute[MemberNames::DATA_TYPE];

        // concatenate the initialize/persist method names
        $intializeMethod = sprintf('initializeProductLinkAttribute%s', $dataType);
        $persistMethod = sprintf('persistProductLinkAttribute%s', $dataType);

        // prepare, initialize and persist the product link attribute int entity
        $this->$persistMethod($this->$intializeMethod($this->prepareAttributes()));
    }
297283
protected function process()
    {

        // query whether or not we've found a bundle product
        if ($this->getValue(ColumnKeys::PRODUCT_TYPE) !== ProductTypes::BUNDLE) {
            return;
        }

        // query whether or not, we've a bundle
        if ($bundleValues = $this->getValue(ColumnKeys::BUNDLE_VALUES)) {
            // initialize the array for the product bundles
            $artefacts = array();

            // load the parent SKU from the row
            $parentSku = $this->getValue(ColumnKeys::SKU);

            // initialize the bundle with the found values
            foreach ($this->explode($bundleValues, '|') as $bundleValue) {
                // initialize the product bundle itself
                $bundle = $this->newArtefact(
                    array(
                        ColumnKeys::BUNDLE_PARENT_SKU    => $parentSku,
                        ColumnKeys::STORE_VIEW_CODE      => $this->getValue(ColumnKeys::STORE_VIEW_CODE),
                        ColumnKeys::BUNDLE_SKU_TYPE      => $this->getValue(ColumnKeys::BUNDLE_SKU_TYPE),
                        ColumnKeys::BUNDLE_PRICE_TYPE    => $this->getValue(ColumnKeys::BUNDLE_PRICE_TYPE),
                        ColumnKeys::BUNDLE_PRICE_VIEW    => $this->getValue(ColumnKeys::BUNDLE_PRICE_VIEW),
                        ColumnKeys::BUNDLE_WEIGHT_TYPE   => $this->getValue(ColumnKeys::BUNDLE_WEIGHT_TYPE),
                        ColumnKeys::BUNDLE_SHIPMENT_TYPE => $this->getValue(ColumnKeys::BUNDLE_SHIPMENT_TYPE),
                    ),
                    array(
                        ColumnKeys::BUNDLE_PARENT_SKU        => ColumnKeys::SKU,
                        ColumnKeys::STORE_VIEW_CODE          => ColumnKeys::STORE_VIEW_CODE,
                        ColumnKeys::BUNDLE_SKU_TYPE          => ColumnKeys::BUNDLE_SKU_TYPE,
                        ColumnKeys::BUNDLE_PRICE_TYPE        => ColumnKeys::BUNDLE_PRICE_TYPE,
                        ColumnKeys::BUNDLE_PRICE_VIEW        => ColumnKeys::BUNDLE_PRICE_VIEW,
                        ColumnKeys::BUNDLE_WEIGHT_TYPE       => ColumnKeys::BUNDLE_WEIGHT_TYPE,
                        ColumnKeys::BUNDLE_SHIPMENT_TYPE     => ColumnKeys::BUNDLE_SHIPMENT_TYPE,
                        ColumnKeys::BUNDLE_VALUE_NAME        => ColumnKeys::BUNDLE_VALUES,
                        ColumnKeys::BUNDLE_VALUE_TYPE        => ColumnKeys::BUNDLE_VALUES,
                        ColumnKeys::BUNDLE_VALUE_REQUIRED    => ColumnKeys::BUNDLE_VALUES,
                        ColumnKeys::BUNDLE_VALUE_SKU         => ColumnKeys::BUNDLE_VALUES,
                        ColumnKeys::BUNDLE_VALUE_PRICE       => ColumnKeys::BUNDLE_VALUES,
                        ColumnKeys::BUNDLE_VALUE_DEFAULT     => ColumnKeys::BUNDLE_VALUES,
                        ColumnKeys::BUNDLE_VALUE_DEFAULT_QTY => ColumnKeys::BUNDLE_VALUES,
                        ColumnKeys::BUNDLE_VALUE_PRICE_TYPE  => ColumnKeys::BUNDLE_VALUES
                    )
                );

                // initialize the columns
                foreach ($this->columns as $columnKey) {
                    $bundle[$columnKey] = null;
                }

                // set the values
                $values = array();
                foreach (explode(',', $bundleValue) as $values) {
                    list ($key, $value) = explode('=', $values);
                    $bundle[$this->columns[$key]] = $value;
                }

                // prepare and append the bundle data
                $artefacts[] = $bundle;
            }

            // append the bundles to the subject
            $this->addArtefacts($artefacts);
        }
    }
1294146
protected function process()
    {

        // add the path => entity ID/store view code mapping
        $this->addPathEntityIdMapping($path = $this->getValue(ColumnKeys::PATH));
        $this->addPathStoreViewCodeMapping($path, $this->getSubject()->getStoreViewCode(StoreViewCodes::ADMIN));

        // temporary persist the path
        $this->setLastPath($path);
    }
366726
protected function process()
    {

        // explode the path into the category names
        if ($categories = $this->explode($this->getValue(ColumnKeys::PATH), '/')) {
            // initialize the artefacts and reset the category IDs
            $artefacts = array();
            $this->categoryIds = array(1);

            // iterate over the category names and try to load the category therefore
            for ($i = 0; $i < sizeof($categories); $i++) {
                try {
                    // prepare the expected category name
                    $categoryPath = implode('/', array_slice($categories, 0, $i + 1));
                    // load the existing category
                    $category = $this->loadCategory($this->mapPath($categoryPath));
                    // prepend the ID the array with the category IDs
                    array_push($this->categoryIds, (integer) $category[MemberNames::ENTITY_ID]);
                } catch (\Exception $e) {
                    // log a message that requested category is NOT available
                    $this->getSystemLogger()->debug(sprintf('Can\'t load category %s, create a new one', $categoryPath));

                    // prepare the static entity values, insert the entity and set the entity ID
                    $category = $this->initializeCategory($this->prepareAttributes());

                    // update the persisted category with the entity ID
                    $category[$this->getPkMemberName()] = $this->persistCategory($category);
                    $category[MemberNames::URL_KEY] = $this->getValue(ColumnKeys::URL_KEY);

                    // append the ID of the new category to array with the IDs
                    array_push($this->categoryIds, $category[MemberNames::ENTITY_ID]);
                }
            }

            // temporary persist primary keys
            $this->updatePrimaryKeys($category);

            // prepare the artefact
            $artefact = array(
                $this->getPkMemberName() => $category[$this->getPkMemberName()],
                MemberNames::PATH        => implode('/', $this->categoryIds)
            );

            // put the artefact on the stack
            $artefacts[] = $artefact;

            // add the artefacts
            $this->addArtefacts($artefacts);
        }
    }
996255
protected function _process()
	{
		$iface = 'MShop_Context_Item_Interface';
		if( !( $this->_additional instanceof $iface ) ) {
			throw new MW_Setup_Exception( sprintf( 'Additionally provided object is not of type "%1$s"', $iface ) );
		}

		$this->_msg( 'Adding warehouse data', 0 );

		$ds = DIRECTORY_SEPARATOR;
		$path = dirname( __FILE__ ) . $ds . 'default' . $ds . 'data' . $ds . 'warehouse.php';

		if( ( $data = include( $path ) ) == false ) {
			throw new MShop_Exception( sprintf( 'No file "%1$s" found for product stock domain', $path ) );
		}

		$manager = MShop_Product_Manager_Factory::createManager( $this->_additional );
		$warehouseManager = $manager->getSubManager( 'stock' )->getSubManager( 'warehouse' );

		$num = $total = 0;
		$item = $warehouseManager->createItem();

		foreach( $data['warehouse'] as $key => $dataset )
		{
			$total++;

			$item->setId( null );
			$item->setCode( $dataset['code'] );
			$item->setLabel( $dataset['label'] );
			$item->setStatus( $dataset['status'] );

			try {
				$warehouseManager->saveItem( $item );
				$num++;
			} catch( MW_DB_Exception $e ) { ; } // if warehouse was already available
		}

		$this->_status( $num > 0 ? $num . '/' . $total : 'OK' );
	}
726060
protected function process()
    {

        // query whether or not, we've found a new SKU => means we've found a new product
        if ($this->hasBeenProcessed($sku = $this->getValue(ColumnKeys::SKU))) {
            return;
        }

        // initialize the arrays for the new category product relations
        $categoryProducts = array();

        // load the category product relations found in the CSV file
        foreach ($this->getValue(ColumnKeys::CATEGORIES, array(), array($this, 'explode')) as $path) {
            // load the category for the found path
            $this->path = trim($path);

            // prepare the product category relation attributes
            if ($attr = $this->prepareAttributes()) {
                // initialize and persist the category product relation relation and add the
                // category ID to the list => necessary to create the URL rewrites later!
                $this->persistCategoryProduct($categoryProduct = $this->initializeCategoryProduct($attr));
                $this->addProductCategoryId($categoryId = $categoryProduct[MemberNames::CATEGORY_ID]);

                // tempoary persist the category ID
                $categoryProducts[] = $categoryId;
            }
        }

        // query whether or not we've to clean up existing category product relations
        if ($this->getSubject()->getConfiguration()->hasParam(ConfigurationKeys::CLEAN_UP_CATEGORY_PRODUCT_RELATIONS) &&
            $this->getSubject()->getConfiguration()->getParam(ConfigurationKeys::CLEAN_UP_CATEGORY_PRODUCT_RELATIONS)
        ) {
            // load the existing category product relations for the product with the given SKU
            $existingCategoryProducts = $this->getProductBunchProcessor()->getCategoryProductsBySku($sku);

            // initialize the counter for the deleted category product relations
            $counter = 0;

            // clean up the existing category product relations
            foreach ($existingCategoryProducts as $categoryId => $categoryProduct) {
                // query whether or not the category product relation exists in the CSV file
                if (!in_array($categoryId, $categoryProducts)) {
                    // if not, delete it from the database
                    $this->getProductBunchProcessor()
                         ->deleteCategoryProduct(array(MemberNames::ENTITY_ID => $categoryProduct[MemberNames::ENTITY_ID]));

                    // raise the counter for the deleted category product relations
                    $counter++;
                }
            }

            // log a message (if any category product relations have been cleaned-up)
            if ($counter > 0) {
                $this->getSubject()
                     ->getSystemLogger()
                     ->warning(
                         $this->getSubject()->appendExceptionSuffix(
                             sprintf(
                                 'Cleaned-up %d category product relation(s) for product with SKU "%s"',
                                 $counter,
                                 $sku
                             )
                         )
                     );
            }
        }
    }
971036
protected function process()
    {

        // initialize the array for the artefacts and the store view codes
        $this->artefacts = array();
        $storeViewCodes = array();

        // load the SKU from the row
        $sku = $this->getValue(ColumnKeys::SKU);

        // prepare the store view code
        $this->getSubject()->prepareStoreViewCode();

        // try to load the store view code
        $storeViewCode = $this->getSubject()->getStoreViewCode(StoreViewCodes::ADMIN);

        // query whether or not we've a store view code
        if ($storeViewCode === StoreViewCodes::ADMIN) {
            // if not, load the websites the product is related with
            $websiteCodes = $this->getValue(ColumnKeys::PRODUCT_WEBSITES, array(), array($this, 'explode'));

            // load the store view codes of all websites
            foreach ($websiteCodes as $websiteCode) {
                $storeViewCodes = array_merge($storeViewCodes, $this->getStoreViewCodesByWebsiteCode($websiteCode));
            }
        } else {
            array_push($storeViewCodes, $storeViewCode);
        }

        // iterate over the available image fields
        foreach ($storeViewCodes as $storeViewCode) {
            // iterate over the store view codes and query if artefacts are already available
            if ($this->hasArtefactsByTypeAndEntityId(ProductUrlRewriteObserver::ARTEFACT_TYPE, $lastEntityId = $this->getSubject()->getLastEntityId())) {
                // if yes, load the artefacs
                $this->artefacts = $this->getArtefactsByTypeAndEntityId(ProductUrlRewriteObserver::ARTEFACT_TYPE, $lastEntityId);

                // override the existing data with the store view specific one
                for ($i = 0; $i < sizeof($this->artefacts); $i++) {
                    // query whether or not a URL key has be specfied and the store view codes are equal
                    if ($this->hasValue(ColumnKeys::URL_KEY) && $this->artefacts[$i][ColumnKeys::STORE_VIEW_CODE] === $storeViewCode) {
                        // update the URL key
                        $this->artefacts[$i][ColumnKeys::URL_KEY] = $this->getValue(ColumnKeys::URL_KEY);

                        // also update filename and line number
                        $this->artefacts[$i][ColumnKeys::ORIGINAL_DATA][ColumnKeys::ORIGINAL_FILENAME] = $this->getSubject()->getFilename();
                        $this->artefacts[$i][ColumnKeys::ORIGINAL_DATA][ColumnKeys::ORIGINAL_LINE_NUMBER] = $this->getSubject()->getLineNumber();
                    }
                }
            } else {
                // if no arefacts are available, append new data
                $artefact = $this->newArtefact(
                    array(
                        ColumnKeys::SKU                => $sku,
                        ColumnKeys::STORE_VIEW_CODE    => $storeViewCode,
                        ColumnKeys::CATEGORIES         => $this->getValue(ColumnKeys::CATEGORIES),
                        ColumnKeys::PRODUCT_WEBSITES   => $this->getValue(ColumnKeys::PRODUCT_WEBSITES),
                        ColumnKeys::VISIBILITY         => $this->getValue(ColumnKeys::VISIBILITY),
                        ColumnKeys::URL_KEY            => $this->getValue(ColumnKeys::URL_KEY)
                    ),
                    array(
                        ColumnKeys::SKU                => ColumnKeys::SKU,
                        ColumnKeys::STORE_VIEW_CODE    => ColumnKeys::STORE_VIEW_CODE,
                        ColumnKeys::CATEGORIES         => ColumnKeys::CATEGORIES,
                        ColumnKeys::PRODUCT_WEBSITES   => ColumnKeys::PRODUCT_WEBSITES,
                        ColumnKeys::VISIBILITY         => ColumnKeys::VISIBILITY,
                        ColumnKeys::URL_KEY            => ColumnKeys::URL_KEY,
                    )
                );

                // append the base image to the artefacts
                $this->artefacts[] = $artefact;
            }
        }

        // append the artefacts that has to be exported to the subject
        $this->addArtefacts($this->artefacts);
    }
359953
protected function process()
    {

        // query whether or not, the image changed
        if ($this->isParentImage($imagePath = $this->getValue(ColumnKeys::IMAGE_PATH))) {
            return;
        }

        // initialize and persist the product media gallery value
        $productMediaGalleryValue = $this->initializeProductMediaGalleryValue($this->prepareAttributes());
        $this->persistProductMediaGalleryValue($productMediaGalleryValue);

        // temporarily persist the image name
        $this->setParentImage($imagePath);
    }
207879
protected function _process()
	{
		$this->_msg( 'Adding catalog promotion performance data', 0 );


		$context =  $this->_getContext();

		$catalogManager = MShop_Catalog_Manager_Factory::createManager( $context );
		$catalogListManager = $catalogManager->getSubManager( 'list' );
		$catalogListTypeManager = $catalogListManager->getSubManager( 'type' );


		$search = $catalogListTypeManager->createSearch();
		$expr = array(
			$search->compare( '==', 'catalog.list.type.domain', 'product' ),
			$search->compare( '==', 'catalog.list.type.code', 'promotion' ),
		);
		$search->setConditions( $search->combine( '&&', $expr ) );
		$types = $catalogListTypeManager->searchItems( $search );

		if ( ( $typeItem = reset( $types ) ) === false ) {
			throw new Exception( 'Catalog list type item not found' );
		}


		$search = $catalogManager->createSearch();
		$search->setSortations( array( $search->sort( '+', 'catalog.level' ), $search->sort( '+', 'catalog.left' ) ) );


		$listItem = $catalogListManager->createItem();
		$listItem->setTypeId( $typeItem->getId() );
		$listItem->setDomain( 'product' );


		$start = 0;

		do
		{
			$this->_txBegin();

			$result = $catalogManager->searchItems( $search );

			foreach( $result as $catId => $catItem )
			{
				$pos = 0;

				$search = $catalogListManager->createSearch();
				$expr = array(
					$search->compare( '==', 'catalog.list.parentid', $catId ),
					$search->compare( '==', 'catalog.list.position', array( 20, 40, 60, 80 ) ),
					$search->compare( '==', 'catalog.list.domain', 'product' ),
					$search->compare( '==', 'catalog.list.type.code', 'default' ),
				);
				$search->setConditions( $search->combine( '&&', $expr ) );

				foreach( $catalogListManager->searchItems( $search ) as $item )
				{
					$listItem->setId( null );
					$listItem->setParentId( $item->getParentId() );
					$listItem->setRefId( $item->getRefId() );
					$listItem->setPosition( $pos++ );

					$catalogListManager->saveItem( $listItem, false );
				}
			}

			$count = count( $result );
			$start += $count;
			$search->setSlice( $start );

			$this->_txCommit();
		}
		while( $count == $search->getSliceSize() );


		$this->_status( 'done' );
	}
1245982
public function processAbandonedCarts()
    {
        $result = [];
        $stores = $this->helper->getStores();
        $this->acPendingContactUpdater->update();

        foreach ($stores as $store) {
            $storeId = $store->getId();
            $websiteId = $store->getWebsiteId();

            $result = $this->processAbandonedCartsForCustomers($storeId, $websiteId, $result);
            $result = $this->processAbandonedCartsForGuests($storeId, $websiteId, $result);
        }

        return $result;
    }
725905
protected function processAdditionalImages()
    {

        // load the store view code
        $storeViewCode = $this->getValue(ColumnKeys::STORE_VIEW_CODE);
        $attributeSetCode = $this->getValue(ColumnKeys::ATTRIBUTE_SET_CODE);

        // load the parent SKU from the row
        $parentSku = $this->getValue(ColumnKeys::SKU);

        // query whether or not, we've additional images
        if ($additionalImages = $this->getValue(ColumnKeys::ADDITIONAL_IMAGES, null, array($this, 'explode'))) {
            // expand the additional image labels, if available
            $additionalImageLabels = $this->getValue(ColumnKeys::ADDITIONAL_IMAGE_LABELS, array(), array($this, 'explode'));

            // initialize the images with the found values
            foreach ($additionalImages as $key => $additionalImage) {
                // prepare the additional image
                $artefact = $this->newArtefact(
                    array(
                        ColumnKeys::STORE_VIEW_CODE    => $storeViewCode,
                        ColumnKeys::ATTRIBUTE_SET_CODE => $attributeSetCode,
                        ColumnKeys::IMAGE_PARENT_SKU   => $parentSku,
                        ColumnKeys::IMAGE_PATH         => $additionalImage,
                        ColumnKeys::IMAGE_PATH_NEW     => $additionalImage,
                        ColumnKeys::IMAGE_LABEL        => isset($additionalImageLabels[$key]) ?
                                                          $additionalImageLabels[$key] :
                                                          $this->getDefaultImageLabel()
                    ),
                    array(
                        ColumnKeys::STORE_VIEW_CODE    => ColumnKeys::STORE_VIEW_CODE,
                        ColumnKeys::ATTRIBUTE_SET_CODE => ColumnKeys::ATTRIBUTE_SET_CODE,
                        ColumnKeys::IMAGE_PARENT_SKU   => ColumnKeys::SKU,
                        ColumnKeys::IMAGE_PATH         => ColumnKeys::ADDITIONAL_IMAGES,
                        ColumnKeys::IMAGE_PATH_NEW     => ColumnKeys::ADDITIONAL_IMAGES,
                        ColumnKeys::IMAGE_LABEL        => ColumnKeys::ADDITIONAL_IMAGE_LABELS
                    )
                );

                // append the additional image to the artefacts
                $this->artefacts[] = $artefact;
            }
        }
    }
582422
public function process()
	{
		$view = $this->getView();

		if( $view->param( 'cs-order', null ) === null ) {
			return;
		}

		try
		{
			$controller = Controller_Frontend_Factory::createController( $this->_getContext(), 'basket' );
			$controller->get()->check( MShop_Order_Item_Base_Abstract::PARTS_ALL );

			parent::process();
		}
		catch( Exception $e )
		{
			$view->standardStepActive = 'summary';
			throw $e;
		}
	}
687176
protected function process()
    {

        // load email and website code
        $email = $this->getValue(ColumnKeys::EMAIL);
        $website = $this->getValue(ColumnKeys::WEBSITE);

        // query whether or not, we've found a customer identifier => means we've found a new customer
        if ($this->isLastIdentifier(array($email, $website))) {
            return;
        }

        // delete the customer with the passed identifier
        $this->deleteCustomer(
            array(
                MemberNames::EMAIL      => $email,
                MemberNames::WEBSITE_ID => $this->getStoreWebsiteIdByCode($this->getValue(ColumnKeys::WEBSITE))
            )
        );

        // flush the cache to remove the deleted customer (which has previously been cached)
        $this->getCustomerBunchProcessor()->cleanUp();
    }
379158
protected function process()
    {

        // initialize the array for the links
        $artefacts = array();

        // load the link type mappings
        $linkTypes = $this->getLinkTypeMappings();

        // prepare the links for the found link types and merge the found artefacts
        foreach ($linkTypes as $linkTypeCode => $columns) {
            $artefacts = array_merge($artefacts, $this->prepareArtefacts($linkTypeCode, $columns));
        }

        // append the links to the subject
        $this->addArtefacts($artefacts);
    }
95681
protected function doProcessing()
    {
        $this->prepareProcessContext();


        // initialization process pipeline

        $initSteps = $this->initProcessSteps();

        if ( ! empty($initSteps)) {

            $this->context = app(Pipeline::class)
                 ->send($this->context)
                 ->through($initSteps)
                 ->then(function (ProcessContextInterface $context) {

                    return $context;
                 });

            $this->afterInitSteps();
        }


        // main pipeline (actual processing)

        $steps = $this->processSteps();

        if ($this->databaseTransaction) DB::beginTransaction();

        try {

            $this->context = app(Pipeline::class)
                 ->send($this->context)
                 ->through($steps)
                 ->then(function(ProcessContextInterface $context) {

                    if ($this->databaseTransaction) DB::commit();

                    return $context;
                 });

        } catch (Exception $e) {

            if ($this->databaseTransaction) DB::rollBack();

            $this->onExceptionInPipeline($e);

            throw $e;
        }

        $this->afterPipeline();


        $this->populateResult();
    }