Returns the products for the given IDs which are in stock

@param \Aimeos\MShop\Context\Item\Iface $context Context item object
@param array $prodIds List of product IDs
@param string $stockType Stock type code
485423
protected function getProducts( \Aimeos\MShop\Context\Item\Iface $context, array $prodIds, $stockType )
	{
		$productCodes = $stockMap = [];
		$productItems = $this->getProductItems( $context, $prodIds );

		foreach( $productItems as $productItem ) {
			$productCodes[] = $productItem->getCode();
		}

		foreach( $this->getStockItems( $context, $productCodes, $stockType ) as $stockItem ) {
			$stockMap[ $stockItem->getProductCode() ] = true;
		}

		foreach( $productItems as $productId => $productItem )
		{
			if( !isset( $stockMap[ $productItem->getCode() ] ) ) {
				unset( $productItems[$productId] );
			}
		}

		return $productItems;
	}
613895
protected function getProductIds( array $productItems )
	{
		$prodIds = [];

		foreach( $productItems as $product )
		{
			if( $product->getType() === 'select' ) {
				$prodIds = array_merge( $prodIds, array_keys( $product->getRefItems( 'product', 'default', 'default' ) ) );
			}
		}

		return $prodIds;
	}
1090458
protected function addItem( \Aimeos\MW\Container\Content\Iface $contentItem, \Aimeos\MShop\Product\Item\Iface $item, $langid )
	{
		$listTypes = [];
		foreach( $item->getListItems( 'text' ) as $listItem ) {
			$listTypes[$listItem->getRefId()] = $listItem->getType();
		}

		foreach( $this->getTextTypes( 'product' ) as $textTypeItem )
		{
			$textItems = $item->getRefItems( 'text', $textTypeItem->getCode() );

			if( !empty( $textItems ) )
			{
				foreach( $textItems as $textItem )
				{
					$listType = ( isset( $listTypes[$textItem->getId()] ) ? $listTypes[$textItem->getId()] : '' );
					$items = array( $langid, $item->getType(), $item->getCode(), $listType, $textTypeItem->getCode(), '', '' );

					// use language of the text item because it may be null
					if( ( $textItem->getLanguageId() == $langid || is_null( $textItem->getLanguageId() ) )
						&& $textItem->getTypeId() == $textTypeItem->getId() )
					{
						$items[0] = $textItem->getLanguageId();
						$items[5] = $textItem->getId();
						$items[6] = $textItem->getContent();
					}

					$contentItem->add( $items );
				}
			}
			else
			{
				$items = array( $langid, $item->getType(), $item->getCode(), 'default', $textTypeItem->getCode(), '', '' );
				$contentItem->add( $items );
			}
		}
	}
527964
protected function fromArray( \Aimeos\MShop\Product\Item\Iface $item, array $data )
	{
		$manager = \Aimeos\MShop::create( $this->getContext(), 'stock' );

		$search = $manager->createSearch();
		$search->setConditions( $search->compare( '==', 'stock.productcode', $item->getCode() ) );
		$stockItems = $manager->searchitems( $search );

		$list = (array) $this->getValue( $data, 'stock.id', [] );

		foreach( $list as $idx => $id )
		{
			$type = $this->getValue( $data, 'stock.type/' . $idx );

			if( isset( $stockItems[$id] ) && $stockItems[$id]->getType() == $type )
			{
				$stockItem = $stockItems[$id];
				unset( $stockItems[$id] );
			}
			else
			{
				$stockItem = $manager->createItem()->setType( $type );
			}

			$stockItem->setProductCode( $item->getCode() );
			$stockItem->setStocklevel( $this->getValue( $data, 'stock.stocklevel/' . $idx ) );
			$stockItem->setDateBack( $this->getValue( $data, 'stock.dateback/' . $idx ) );

			$manager->saveItem( $stockItem, false );
		}

		$manager->deleteItems( array_keys( $stockItems ) );
	}
362058
public function updateStock(
        PurchasableInterface $purchasable,
        $stockToDecrease
    ) {
        $namespace = $this->getPurchasableNamespace();
        if (!$purchasable instanceof $namespace) {
            return false;
        }

        /**
         * @var $purchasable PackInterface
         */
        $stockType = $purchasable->getStockType();
        if ($stockType === ElcodiProductStock::INHERIT_STOCK) {
            return $this->updateStockOfPurchasablesByLoadedStockUpdaters(
                $purchasable->getPurchasables(),
                $stockToDecrease
            );
        }

        $decreasedStock = $this->updateSimplePurchasableStock(
            $purchasable,
            $stockToDecrease
        );

        if ($decreasedStock) {
            $this
                ->packObjectManager
                ->flush($purchasable);
        }

        return $decreasedStock;
    }
345305
protected function rebuildIndex( array $prodIds )
	{
		$context = $this->getContext();
		$productManager = \Aimeos\MShop\Factory::createManager( $context, 'product' );

		$search = $productManager->createSearch();
		$search->setConditions( $search->compare( '==', 'product.id', $prodIds ) );
		$search->setSlice( 0, count( $prodIds ) );

		$indexManager = \Aimeos\MShop\Factory::createManager( $context, 'index' );
		$indexManager->rebuildIndex( $productManager->searchItems( $search ) );
	}
630384
private function get_context_courseid(\context $context) {

        if (empty($this->contextcourseids[$context->id])) {

            $coursecontext = $context->get_course_context(false);
            if (!$coursecontext) {
                // Default to the frontpage course context.
                $coursecontext = \context_course::instance(SITEID);
            }
            $this->contextcourseids[$context->id] = $coursecontext->instanceid;
        }

        return $this->contextcourseids[$context->id];
    }
781742
protected function _getParentProduct($sParentId)
    {
        if ($sParentId && $this->_oParentProd === null) {
            $this->_oParentProd = false;
            $oProduct = oxNew(\OxidEsales\Eshop\Application\Model\Article::class);
            if (($oProduct->load($sParentId))) {
                $this->_processProduct($oProduct);
                $this->_oParentProd = $oProduct;
            }
        }

        return $this->_oParentProd;
    }
1134974
protected function addUserGroups( \Aimeos\MShop\Context\Item\Iface $context )
	{
		$username = '';
		$token = $this->container->get( 'security.token_storage' )->getToken();

		if( is_object( $token ) && is_object( $token->getUser() ) && method_exists( $token->getUser(), 'getId' ) )
		{
			$username =  $token->getUser()->getUsername();
			$userid = $token->getUser()->getId();
			$context->setUserId( $userid );
			$context->setGroupIds( function() use ( $context, $userid )
			{
				$manager = \Aimeos\MShop::create( $context, 'customer' );
				return $manager->getItem( $userid, array( 'customer/group' ) )->getGroups();
			} );
		}

		if( $username === '' && $this->container->has( 'request_stack' )
			&& ( $request = $this->container->get('request_stack')->getMasterRequest() ) !== null
		) {
			$username = $request->getClientIp();
		}

		return $context->setEditor( $username );
	}
1090262
protected function updateProducts( \Aimeos\MW\View\Iface $view )
	{
		$controller = \Aimeos\Controller\Frontend::create( $this->getContext(), 'basket' );
		$products = (array) $view->param( 'b_prod', [] );

		if( ( $position = $view->param( 'b_position', '' ) ) !== '' )
		{
			$products[] = array(
				'position' => $position,
				'quantity' => $view->param( 'b_quantity', 1 )
			);
		}

		foreach( $products as $values )
		{
			$controller->updateProduct(
				( isset( $values['position'] ) ? (int) $values['position'] : 0 ),
				( isset( $values['quantity'] ) ? (int) $values['quantity'] : 1 )
			);
		}

		$this->clearCached();
	}
831353
private function getItemData($identifiers, array $attributes, array $context)
    {
        return $this->itemDataProvider->getItem($attributes['resource_class'], $identifiers, $attributes['item_operation_name'], $context);
    }
1121947
public static function preload_contexts_by_id(array $contextids) {
        global $DB;

        // Determine which contexts are not already cached.
        $tofetch = [];
        foreach ($contextids as $contextid) {
            if (!self::cache_get_by_id($contextid)) {
                $tofetch[] = $contextid;
            }
        }

        if (count($tofetch) > 1) {
            // There are at least two to fetch.
            // There is no point only fetching a single context as this would be no more efficient than calling the existing code.
            list($insql, $inparams) = $DB->get_in_or_equal($tofetch, SQL_PARAMS_NAMED);
            $ctxs = $DB->get_records_select('context', "id {$insql}", $inparams, '',
                    \context_helper::get_preload_record_columns_sql('{context}'));
            foreach ($ctxs as $ctx) {
                self::preload_from_record($ctx);
            }
        }
    }
462704
protected static function addDatabaseManager( \Aimeos\MShop\Context\Item\Iface $context )
	{
		if( isset( $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['aimeos']['aimeos_context_dbm'] )
			&& is_callable( ( $fcn = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['aimeos']['aimeos_context_dbm'] ) )
		) {
			return $fcn( $context );
		}

		return $context->setDatabaseManager( new \Aimeos\MW\DB\Manager\DBAL( $context->getConfig() ) );
	}
857039
protected static function addProcess( \Aimeos\MShop\Context\Item\Iface $context )
	{
		if( isset( $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['aimeos']['aimeos_context_process'] )
			&& is_callable( ( $fcn = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['aimeos']['aimeos_context_process'] ) )
		) {
			return $fcn( $context );
		}

		$process = new \Aimeos\MW\Process\Pcntl( \Aimeos\Aimeos\Base::getExtConfig( 'pcntlMax', 4 ) );

		// Reset before child processes are spawned to avoid lost DB connections afterwards (TYPO3 9.4 and above)
		if( $process->isAvailable() === false
			|| version_compare( TYPO3_version, '9.4' ) < 0
			|| method_exists( '\TYPO3\CMS\Core\Database\ConnectionPool', 'resetConnections' ) === false
		) {
			$process = new \Aimeos\MW\Process\None();
		}

		return $context->setProcess( $process );
	}
308812
protected function editItems( \Aimeos\MW\View\Iface $view, array $ids )
	{
		$context = $this->getContext();
		$cntl = \Aimeos\Controller\Frontend::create( $context, 'customer' );
		$item = $cntl->uses( ['product' => ['watch']] )->get();

		$config = [
			'timeframe' => $view->param( 'wat_timeframe', 7 ),
			'pricevalue' => $view->param( 'wat_pricevalue', '0.00' ),
			'price' => $view->param( 'wat_price', 0 ),
			'stock' => $view->param( 'wat_stock', 0 ),
			'currency' => $context->getLocale()->getCurrencyId(),
		];

		foreach( $ids as $id )
		{
			if( ( $listItem = $item->getListItem( 'product', 'watch', $id ) ) !== null )
			{
				$time = time() + ( $config['timeframe'] + 1 ) * 86400;
				$listItem = $listItem->setDateEnd( date( 'Y-m-d 00:00:00', $time ) )->setConfig( $config );

				$cntl->addListItem( 'product', $listItem );
			}
		}

		$cntl->store();
	}
117262
public function getChildrenProductIds($minProductId, $maxProductId)
    {
        $this->childrenProductIds = [];

        $superLinkTable = $this->getTable('catalog_product_super_link');

        $superLinkQuery = $this->_resource->getConnection()->select()
            ->from($superLinkTable, ['product_id', 'parent_id'])
            ->where('parent_id >= ?', $minProductId)
            ->where('parent_id <= ?', $maxProductId);

        $this->iterator->walk(
            (string)$superLinkQuery,
            [[$this, 'handleChildrenProductId']],
            [],
            $this->_resource->getConnection()
        );

        return $this->childrenProductIds;
    }
534484
protected function _checkCategory( $prodid )
	{
		$catalogListManager = MShop_Factory::createManager( $this->_getContext(), 'catalog/list' );

		$search = $catalogListManager->createSearch( true );
		$expr = array(
			$search->compare( '==', 'catalog.list.refid', $prodid ),
			$search->getConditions()
		);
		$search->setConditions( $search->combine( '&&', $expr ) );
		$search->setSlice( 0, 1 );

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

		if( reset( $result ) === false )
		{
			$msg = sprintf( 'Adding product with ID "%1$s" is not allowed', $prodid );
			throw new Controller_Frontend_Basket_Exception( $msg );
		}
	}