helper = $helper; $this->resultRaw = $resultRaw; $this->request = $request; $this->urlHelper = $urlHelper; $this->urlDecoder = $urlDecoder; $this->layout = $layout; $this->registry = $registry; $this->json = $json; } /** * @param string $html * @return string */ public function removeArgs($html) { $html = str_replace(['?' . static::AJAX_ATTR . '=1&', '?' . static::AJAX_ATTR . '=1&'], '?', $html); $html = str_replace([ '?' . static::AJAX_ATTR . '=1', '&' . static::AJAX_ATTR . '=1', '&' . static::AJAX_ATTR . '=1', ], '', $html); return $html; } public function removeEncodedArgsItem($match) { $code_string = $match[0]; $url = $this->urlDecoder->decode($code_string); if (false !== $url) { $newUrl = $this->urlHelper->removeRequestParam($url, static::AJAX_ATTR); $newUrl = $this->removeEncodedArgs($newUrl); if ($url != $newUrl) { $code_string = $this->urlHelper->getEncodedUrl($newUrl); } } return $code_string; } /** * @param string $html * @return string */ public function removeEncodedArgs($html) { $_html = preg_replace_callback(static::REGEX_URLS, [$this, 'removeEncodedArgsItem'], $html); if ($_html) { $html = $_html; } return $html; } /** * @return bool */ protected function isAjax() { return $this->helper->isEnabled() && $this->request->isXmlHttpRequest() && $this->request->isAjax() && $this->request->getParam(static::AJAX_ATTR, ''); } protected function getAjaxContent() { /** @var LayoutInterface $layout */ $layout = $this->layout; $layout->getOutput(); // @todo temporary fix: magenta ignoring the product limit parameter per page, per page with ajax request $blocks = $this->getLayoutBlock($layout); $page = (int)$this->request->getParam('p', 1); $firstNum = 0; $lastNum = 0; $productsCount = 0; $isFirst = false; $isLast = false; if ($blocks['products']) { $collection = $blocks['products']->getLoadedProductCollection(); $pageSize = $collection->getPageSize() * 1; $firstNum = $pageSize * ($page - 1) + 1; $lastNum = $pageSize * ($page - 1) + $collection->count(); $productsCount = $collection->getSize(); $isFirst = $firstNum <= 1; $isLast = $lastNum >= $productsCount; } $html = []; $cache_tags = []; foreach ($blocks as $key => $block) { $cache_tags = $this->addIdentities($block, $cache_tags); $html[$key] = $block ? $block->toHtml() : ''; } $response = compact('productsCount', 'page', 'pageSize', 'firstNum', 'lastNum', 'isFirst', 'isLast', 'html'); $response['html']['_before'] = ''; $response['html']['_after'] = ''; try { $response = $this->prepareForPlugins($response, $blocks); } catch ( Exception $exception){ // @todo do nothing or log } $response = $this->changeResponse($response, $cache_tags, $page); return $response; } /** * @param LayoutInterface $layout * @return array */ protected function getLayoutBlock($layout) { return [ 'products' => $layout->getBlock(self::BLOCK_PRODUCTS) ?: $layout->getBlock(self::BLOCK_PRODUCTS_SEARCH), ]; } protected function addIdentities($block, array $data = []) { if ($block instanceof IdentityInterface) { $data = array_merge($data, $block->getIdentities()); } return $data; } /** * @param array $response * @param array $blocks * @return array * @throws LocalizedException */ protected function prepareForPlugins(array $response, array $blocks) { if (array_key_exists('products', $blocks) && class_exists('\Amasty\Label\Plugin\Catalog\Product\ListProduct')) { /** @var ListProduct $amastyLabelListProduct */ $amastyLabelListProduct = ObjectManager::getInstance()->get('\Amasty\Label\Plugin\Catalog\Product\ListProduct'); $this->registry->register('amlabel_category_observer', false); $blocks['products']->setIsAmLabelObserved(false); $response['html']['_after'] .= $amastyLabelListProduct->afterToHtml($blocks['products'], ''); } return $response; } protected function changeResponse($response, $cache_tags) { $cache_tags[] = Type::CACHE_TAG; $cache_tags = array_unique($cache_tags); $cache_tags = implode(',', $cache_tags); $response['cache_tags'] = $cache_tags; $response['html'] = array_map([$this, 'removeArgs'], $response['html']); $response['html'] = array_map([$this, 'removeEncodedArgs'], $response['html']); return $response; } protected function json(array $data) { $response = $this->resultRaw->create(); $response->setHeader('Content-type', 'application/json'); if (array_key_exists('cache_tags', $data)) { if (!empty($data['cache_tags'])) { $response->setHeader('X-Magento-Tags', $data['cache_tags']); } unset($data['cache_tags']); } $data = $this->json->serialize($data); $response->setContents($data); return $response; } }