Magento 2 .2 - Wie füge ich der Produkt-URL ein statisches Produktpräfix hinzu?

8

Ich möchte Produkt-URLs ein Produktpräfix (statischer Pfad) hinzufügen.

So etwas wie www.test.com/product-prefix/product1.html

Daher folgen alle Produkt-URLs der Website derselben Struktur - www.test.com/product-prefix/product2.html

Wobei Produktpräfix ein statisches Produktpräfix ist.

Ich möchte es als statisch hinzufügen, kein URL-Rewrite-Konzept.

Ich habe die Kerndatei ProductUrlPathGenerator.php überprüft, aber keine genaue Lösung erhalten. Kann jemand helfen und den besseren Weg vorschlagen?

Magento Version - 2.2

Manthan Dave
quelle
Vielen Dank für Ihre Lösung. Ich habe es genauso gemacht, aber es funktioniert nicht für mich. Ich verwende die Magento 2.2.6-Version. Können Sie mir bitte dabei helfen?
Anurag Rana

Antworten:

8

Nach ein paar Stunden Debugging habe ich dieses Problem durch Befolgen der folgenden Methode behoben.

Ich habe zwei Dateien in meinem benutzerdefinierten Modul überschrieben, eine ist das Produkt-URL-Modell und eine andere ist Router Controller \ Router

Unten ist die di.xml

<preference for="Magento\Catalog\Model\Product\Url" type="Vendor\ModuleName\Model\Url" />
<preference for="Magento\UrlRewrite\Controller\Router" type="Vendor\ModuleName\Controller\Router" />

Code für Url.php

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * Product Url model
 *
 * @author     Magento Core Team <[email protected]>
 */
namespace Vendor\ModuleName\Model;

use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;

class Url extends \Magento\Catalog\Model\Product\Url
{
    /**
     * URL instance
     *
     * @var \Magento\Framework\UrlFactory
     */
    protected $urlFactory;

    /**
     * @var \Magento\Framework\Filter\FilterManager
     */
    protected $filter;

    /**
     * Store manager
     *
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var \Magento\Framework\Session\SidResolverInterface
     */
    protected $sidResolver;

    /** @var UrlFinderInterface */
    protected $urlFinder;

    /**
     * @param \Magento\Framework\UrlFactory $urlFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Framework\Filter\FilterManager $filter
     * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
     * @param UrlFinderInterface $urlFinder
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\UrlFactory $urlFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Filter\FilterManager $filter,
        \Magento\Framework\Session\SidResolverInterface $sidResolver,
        UrlFinderInterface $urlFinder,
        array $data = []
    ) {
        parent::__construct($urlFactory, $storeManager, $filter, $sidResolver, $urlFinder, $data);
        $this->urlFactory = $urlFactory;
        $this->storeManager = $storeManager;
        $this->filter = $filter;
        $this->sidResolver = $sidResolver;
        $this->urlFinder = $urlFinder;
    }

    /**
     * Retrieve URL Instance
     *
     * @return \Magento\Framework\UrlInterface
     */
    private function getUrlInstance()
    {
        return $this->urlFactory->create();
    }

    /**
     * Retrieve URL in current store
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param array $params the URL route params
     * @return string
     */
    public function getUrlInStore(\Magento\Catalog\Model\Product $product, $params = [])
    {
        $params['_scope_to_url'] = true;
        return $this->getUrl($product, $params);
    }

    /**
     * Retrieve Product URL
     *
     * @param  \Magento\Catalog\Model\Product $product
     * @param  bool $useSid forced SID mode
     * @return string
     */
    public function getProductUrl($product, $useSid = null)
    {
        if ($useSid === null) {
            $useSid = $this->sidResolver->getUseSessionInUrl();
        }

        $params = [];
        if (!$useSid) {
            $params['_nosid'] = true;
        }

        return $this->getUrl($product, $params);
    }

    /**
     * Format Key for URL
     *
     * @param string $str
     * @return string
     */
    public function formatUrlKey($str)
    {
        return $this->filter->translitUrl($str);
    }

    /**
     * Retrieve Product URL using UrlDataObject
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param array $params
     * @return string
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function getUrl(\Magento\Catalog\Model\Product $product, $params = [])
    {
        $routePath = '';
        $routeParams = $params;

        $storeId = $product->getStoreId();

        $categoryId = null;

        if (!isset($params['_ignore_category']) && $product->getCategoryId() && !$product->getDoNotUseCategoryId()) {
            $categoryId = $product->getCategoryId();
        }

        if ($product->hasUrlDataObject()) {
            $requestPath = $product->getUrlDataObject()->getUrlRewrite();
            $routeParams['_scope'] = $product->getUrlDataObject()->getStoreId();
        } else {
            $requestPath = $product->getRequestPath();
            if (empty($requestPath) && $requestPath !== false) {
                $filterData = [
                    UrlRewrite::ENTITY_ID => $product->getId(),
                    UrlRewrite::ENTITY_TYPE => \Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator::ENTITY_TYPE,
                    UrlRewrite::STORE_ID => $storeId,
                ];
                if ($categoryId) {
                    $filterData[UrlRewrite::METADATA]['category_id'] = $categoryId;
                }
                $rewrite = $this->urlFinder->findOneByData($filterData);
                if ($rewrite) {
                    $requestPath = $rewrite->getRequestPath();
                    $product->setRequestPath($requestPath);
                } else {
                    $product->setRequestPath(false);
                }
            }
        }

        if (isset($routeParams['_scope'])) {
            $storeId = $this->storeManager->getStore($routeParams['_scope'])->getId();
        }

        if ($storeId != $this->storeManager->getStore()->getId()) {
            $routeParams['_scope_to_url'] = true;
        }

        if (!empty($requestPath)) {
            $routeParams['_direct'] = $requestPath;
        } else {
            $routePath = 'catalog/product/view';
            $routeParams['id'] = $product->getId();
            $routeParams['s'] = $product->getUrlKey();
            if ($categoryId) {
                $routeParams['category'] = $categoryId;
            }
        }

        // reset cached URL instance GET query params
        if (!isset($routeParams['_query'])) {
            $routeParams['_query'] = [];
        }
$baseUrl = $this->storeManager->getStore()->getBaseUrl();
        $productUrl = $this->getUrlInstance()->setScope($storeId)->getUrl($routePath, $routeParams);

        $remainingUrl = str_replace($baseUrl, '', $productUrl);

        $productUrl = $baseUrl."your-static-prefix/" . $remainingUrl;
        //return $this->getUrlInstance()->setScope($storeId)->getUrl($routePath, $routeParams);
        return $productUrl;
    }
}

Code für Controller Router.php

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Vendor\ModuleName\Controller;

use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
use Magento\UrlRewrite\Model\OptionProvider;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;

/**
 * UrlRewrite Controller Router
 */
class Router implements \Magento\Framework\App\RouterInterface
{
    /** var \Magento\Framework\App\ActionFactory */
    protected $actionFactory;

    /** @var \Magento\Framework\UrlInterface */
    protected $url;

    /** @var \Magento\Store\Model\StoreManagerInterface */
    protected $storeManager;

    /** @var \Magento\Framework\App\ResponseInterface */
    protected $response;

    /** @var UrlFinderInterface */
    protected $urlFinder;

    /**
     * @param \Magento\Framework\App\ActionFactory $actionFactory
     * @param \Magento\Framework\UrlInterface $url
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Framework\App\ResponseInterface $response
     * @param UrlFinderInterface $urlFinder
     */
    public function __construct(
        \Magento\Framework\App\ActionFactory $actionFactory,
        \Magento\Framework\UrlInterface $url,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\App\ResponseInterface $response,
        UrlFinderInterface $urlFinder
    ) {
        $this->actionFactory = $actionFactory;
        $this->url = $url;
        $this->storeManager = $storeManager;
        $this->response = $response;
        $this->urlFinder = $urlFinder;
    }

    /**
     * Match corresponding URL Rewrite and modify request
     *
     * @param \Magento\Framework\App\RequestInterface $request
     * @return \Magento\Framework\App\ActionInterface|null
     */
    public function match(\Magento\Framework\App\RequestInterface $request)
    {
        if ($fromStore = $request->getParam('___from_store')) {
            $oldStoreId = $this->storeManager->getStore($fromStore)->getId();
            $oldRewrite = $this->getRewrite($request->getPathInfo(), $oldStoreId);
            if ($oldRewrite) {
                $rewrite = $this->urlFinder->findOneByData(
                    [
                        UrlRewrite::ENTITY_TYPE => $oldRewrite->getEntityType(),
                        UrlRewrite::ENTITY_ID => $oldRewrite->getEntityId(),
                        UrlRewrite::STORE_ID => $this->storeManager->getStore()->getId(),
                        UrlRewrite::IS_AUTOGENERATED => 1,
                    ]
                );
                if ($rewrite && $rewrite->getRequestPath() !== $oldRewrite->getRequestPath()) {
                    return $this->redirect($request, $rewrite->getRequestPath(), OptionProvider::TEMPORARY);
                }
            }
        }
        //Below i have replaced static prefix

        $replaceUrl = str_replace("your-static-prefix/", "", $request->getPathInfo());
        $rewrite = $this->getRewrite($replaceUrl, $this->storeManager->getStore()->getId());

        //$rewrite = $this->getRewrite($request->getPathInfo(), $this->storeManager->getStore()->getId());

        // CODE FOR CATEGORY REWRITE
        if ($rewrite === null) 
        {
            $pathInfo = $request->getPathInfo();
            $pathInfoArray = explode("/", $pathInfo);

            $key = "";
            if(!empty(trim($pathInfoArray[count($pathInfoArray) - 1])))
                $key = trim($pathInfoArray[count($pathInfoArray) - 1]);
            elseif(!empty(trim($pathInfoArray[count($pathInfoArray) - 2])))
                $key = trim($pathInfoArray[count($pathInfoArray) - 2]);

            if($key != "")
            {
                $objectManaer = \Magento\Framework\App\ObjectManager::getInstance();
                $category = $objectManaer->create('Magento\Catalog\Model\Category');
                $collection = $category->getCollection()->addAttributeToFilter('url_key', ['like' => '%' . $key . '%']);

                if($collection->count())
                {
                    $category = $collection->getFirstItem();
                    $path = $category->getPath();
                    $pathArray = explode("/", $category->getPath());

                    foreach(['1', '2', $category->getId()] as $del_val)
                    {
                        if (($categoryId = array_search($del_val, $pathArray)) !== false) {
                            unset($pathArray[$categoryId]);
                        }
                    }

                    $keyArray = [];
                    if(count($pathArray))
                    {
                        foreach($pathArray as $pathId)
                        {
                            $pathCategory = $objectManaer->create('Magento\Catalog\Model\Category')->load($pathId);
                            $keyArray[] = $pathCategory->getUrlKey();
                        }
                    }

                    $keyArray[] = $category->getUrlKey();
                    $key = implode("/", $keyArray);
                    $key = '/' . $key;
                    $rewrite = $this->getRewrite($key, $this->storeManager->getStore()->getId());
                }
            }
        }

        if ($rewrite === null) {
            return null;
        }

        if ($rewrite->getRedirectType()) {
            return $this->processRedirect($request, $rewrite);
        }

        $request->setAlias(\Magento\Framework\UrlInterface::REWRITE_REQUEST_PATH_ALIAS, $rewrite->getRequestPath());
        $request->setPathInfo('/' . $rewrite->getTargetPath());
        return $this->actionFactory->create('Magento\Framework\App\Action\Forward');
    }

    /**
     * @param \Magento\Framework\App\RequestInterface $request
     * @param UrlRewrite $rewrite
     * @return \Magento\Framework\App\ActionInterface|null
     */
    protected function processRedirect($request, $rewrite)
    {
        $target = $rewrite->getTargetPath();
        if ($rewrite->getEntityType() !== Rewrite::ENTITY_TYPE_CUSTOM
            || ($prefix = substr($target, 0, 6)) !== 'http:/' && $prefix !== 'https:'
        ) {
            $target = $this->url->getUrl('', ['_direct' => $target]);
        }
        return $this->redirect($request, $target, $rewrite->getRedirectType());
    }

    /**
     * @param \Magento\Framework\App\RequestInterface $request
     * @param string $url
     * @param int $code
     * @return \Magento\Framework\App\ActionInterface
     */
    protected function redirect($request, $url, $code)
    {
        $this->response->setRedirect($url, $code);
        $request->setDispatched(true);
        return $this->actionFactory->create('Magento\Framework\App\Action\Redirect');
    }

    /**
     * @param string $requestPath
     * @param int $storeId
     * @return UrlRewrite|null
     */
    protected function getRewrite($requestPath, $storeId)
    {
        return $this->urlFinder->findOneByData([
            UrlRewrite::REQUEST_PATH => trim($requestPath, '/'),
            UrlRewrite::STORE_ID => $storeId,
        ]);
    }
}
Manthan Dave
quelle
Das ist sehr gut.
Purushotam Sangroula
@Manthan - Funktioniert Ihre Lösung, wenn ich der Produkt-URL einen benutzerdefinierten Attributwert (z. B. "Marke") als Präfix hinzufügen möchte?
Manashvi Birla
@ ManashviBirla - Ja, es könnte funktionieren - haben Sie das gleiche versucht
Manthan Dave
@ManthanDave: Danke, dass Sie die detaillierte Lösung geschrieben haben. Was würden Sie vorschlagen, wenn wir nur für einige Produkte einen statischen Pfad hinzufügen möchten?
Narendra Vyas
Finden Sie dies auch nicht ausreichend, um einen statischen Pfad für ein Produkt nur von einer Stelle aus hinzuzufügen. Ich meine, ist es in irgendeiner Weise möglich, dass ein Produkt zwei URLs hat, eine als Standard und eine mit dem statischen Pfad (ich weiß, dass dies nicht machbar ist, aber es ist meine Anforderung).
Narendra Vyas
0

Sie sollten in der Lage sein, das gleiche Ergebnis zu erzielen, aber viel weniger ausführlich und ohne das gesamte Modell mit dem Plugin neu zu schreiben.

Anbieter / Modul / etc / di.xml

<?xml version="1.0" />
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Model\Product\Url">
        <plugin name="VendorProductUrl" type="Vendor\Module\Plugin\UrlPlugin" />
    </type>
</config>

Hersteller / Modul / Plugin / UrlPlugin.php

namespace Vendor\Module\Plugin;

use Magento\Store\Model\StoreManagerInterface as StoreManager;

class UrlPlugin
{

    /**
     * Store manager
     *
     * @var StoreManager
     */
     protected $_storeManager;

     public function __construct(
         StoreManager $_storeManager
     )
     {
        $this->_storeManager = $_storeManager;
     }

     /**
      * @param \Magento\Catalog\Model\Product\Url $subject
      * @param string $url
      * @return string
      */
     public function afterGetUrl(\Magento\Catalog\Model\Product\Url $subject, $url)
     {

         $baseUrl = $this->_storeManager->getStore()->getBaseUrl();
         return str_replace($baseUrl, $baseUrl."product-prefix/", $url);
     }
}
GuWa
quelle