magento2: [2.1] Unable to get store URL from admin

Preconditions (*)

Magento 2.4-develop

Steps to reproduce (*)

  1. Install Magento from develop branch.
  2. Run the following code from the admin area (by example from a controller):
$url = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')
    ->getStore(1) // 1 = default store id
    ->getUrl('myroute')

echo $url;

Expected result (*)

http://mymagentoshop.local/myroute

Actual result (*)

Magento returns an URL prefixed with the admin path:

http://mymagentoshop.local/admin_XXXX/myroute

Note

The following code:

$url = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')
    ->getStore($customer->getStoreId())
    ->getBaseUrl();

Works correctly:

http://mymagentoshop.local/

This problem seems to be limited to the “getUrl” method.

This issue was not present with Magento 2.0.7.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 31 (10 by maintainers)

Most upvoted comments

A workaround to get a frontend URL for a store in the backend:

See how Magento is generating the “View” link in the CMS page admin grid via its page actions: Magento\Cms\Ui\Component\Listing\Column\PageActions. It injects the following class in order to build the URL: Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder, which uses \Magento\Framework\UrlInterface. Well, that UrlInterface has a frontend model and a backend model.

In the CMS module’s etc/adminhtml/di.xml, it injects the frontend URL model for that interface:

<type name="Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder">
    <arguments>
        <argument name="frontendUrlBuilder" xsi:type="object">Magento\Framework\Url</argument>
    </arguments>
</type>

If you don’t do this, no matter how you pass it the proper scope, it always resets that scope after getting the base URL. Not good.

Anyhow, I was able to get it working then by doing what Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder is doing, and using di.xml to pass it the proper URL model. Nevertheless, this should be fixed. There is no reason why I shouldn’t be able to just call getUrl() from a store model in the backend.

@magento I am working on it

@drpayyne, Magento\Framework\UrlInterface has two preferences, one in /vendor/magento/magento2-base/app/etc/di.xml and the other in /vendor/magento/module-backend/etc/adminhtml/di.xml

When you’re in the adminhtml area, it uses the preference from magento/module-backend, causing it to become a Magento\Backend\Model\UrlInterface and giving you an unexpected result.

Product URL I had the same problem with a colleague of mine today when we tried to get the URL of a product.

Magento\Catalog\Model\Product uses the Magento\Catalog\Model\Product\Url class which in turns uses the Magento\Framework\UrlFactory which uses the Magento\Framework\UrlInterface, causing the same exact problem as in the Magento\Store\Model\Store class.

We eventually solved our problem with two virtual types and a type.

<type name="ourClass">
    <arguments>
        <argument name="urlBuilder" xsi:type="object">virtualProductUrl</argument>
    </arguments>
</type>

<virtualType name="virtualProductUrl" type="Magento\Catalog\Product\Url">
    <arguments>
        <argument name="urlFactory" xsi:type="object">virtualUrlFactory</argument>
    </arguments>
</virtualType>

<virtualType name="virtualUrlFactory" type="Magento\Framework\UrlFactory">
    <arguments>
        <argument name="instanceName" xsi:type="string">Magento\Framework\Url</argument>
    </arguments>
</virtualType>

In my opinion this is really dirty, but at the same time, we tried a bunch of stuff such as emulate the area before creating the Magento\Catalog\Model\Product using the Magento\Catalog\Model\ProductFactory, e.t.c, but nothing really seemed to work.