Magento – Magento 2.2.8 – sitemap.xml contains “pub” DIR in the URL, It should be without “pub” directory in the URL

croncronjobsmagento2magento2.2.8sitemaps

Preconditions

app/etc/env.php

'directories' => [ 'document_root_is_pub' => true ],

'MAGE_MODE' => 'production',
  • document_root_is_pub is true
  • MAGE_MODE is have production value

sitemap.xml

  • Filename : sitemap.xml
  • Path : /media/

Admin => Stores => Configuration => General => Web:

  • Base Urls => Base URL for User Media Files =>{{unsecure_base_url}}media/

  • Base URLs (Secure) => Secure Base URL for User Media Files => {{secure_base_url}}media/



But while generating the sitemap.xml via cron

Expected result

Actual result



NOTE : When sitemap is generated from admin panel sitemap contains the proper urls, But somehow with cron it comes wrong url (contains pub in the url)



Most likely reason (Might be) But not in my case

Sometime problem happens when running the sitemap generation through
bin/magento cron:run from outside of the Magento directory.

  • e.g our magento code is in /var/www/src, if I run php src/bin/magento cron:run from /var/www the urls will contain src as part of the
    baseurl.
  • Running from the magento directory, e.g php bin/magento cron:run from
    /var/www/src, works as expected.
  • But my cron is generating from /var/www/src
  • And Running from ADMIN UI – Site generate will also works as
    expected.

Any solution or advise will be really helpful.

Best Answer

The reason is the way getBaseUrl function implemented on Magento\Store\Model\Store.

    public function getBaseUrl($type = UrlInterface::URL_TYPE_LINK, $secure = null)
    {
        ...
                case UrlInterface::URL_TYPE_MEDIA:
                    $url = $this->_getMediaScriptUrl($this->filesystem, $secure);
                    if (!$url) {
                        $path = $secure ? self::XML_PATH_SECURE_BASE_MEDIA_URL : self::XML_PATH_UNSECURE_BASE_MEDIA_URL;
                        $url = $this->getConfig($path);
                        if (!$url) {
                            $url = $this->getBaseUrl(UrlInterface::URL_TYPE_WEB, $secure)
                                . $this->filesystem->getUri(DirectoryList::MEDIA);
                        }
                    }
                    break;
        ...
    }

If you don't have a value set for Base URL for User Media Files (and/or Secure Base URL for User Media Files) under Store > Settings > Configuration > General > Web > Base URLs (and/or Base URLs (Secure)) then $url = $this->getConfig($path); will return null, causing the last if condition create the $url.

As it's seen, that if condition has a wrong implementation of combining base URL with media Directory.

When you are running your cronjob under /var/www/src, media directory is under pub/media/. Because of the problematic part of the function, here how your base media URL gets created:

if (!$url) {
   $url = $this->getBaseUrl(UrlInterface::URL_TYPE_WEB, $secure) //"https://magento-site/"
       . $this->filesystem->getUri(DirectoryList::MEDIA); //"pub/media/"
     // = "https://magento-site/pub/media/"
}

Solution is to set;

  • Store > Settings > Configuration > General > Web > Base URLs > Base URL for User Media Files value to {{unsecure_base_url}}media/,
  • Store > Settings > Configuration > General > Web > Base URLs > Secure Base URL for User Media Files value to {{secure_base_url}}media/,

and refresh Configuration cache.

Related Topic