6

I just discovered that the official Magento 2.0 release (post public beta) doesn't support loading static assets from a symlinked folder. The root of the problem appears to be here

#File: vendor/magento/framework/View/Design/FileResolution/Fallback/Resolver/Simple.php

if ($this->rootDirectory->isExist($this->rootDirectory->getRelativePath($path))) {
    return $path;
}

The call to $this->rootDirectory->getRelativePath fails if the file doesn't exist under the root Magento directory. So, if you've created a symlink for your module folder

lns app/code/My/Module /path/to/my/other/repository/My/Module

the static file loader application won't be able to find your file.

Does anyone know a workaround for this that doesn't involve

  • running php bin/magento setup:static-content:deploy whenever you change a file
  • hacking some code directly into vendor/magento/framework/View/Design/FileResolution/Fallback/Resolver/Simple.php to specifically handle your symlink-ed files
4
  • I've not looked into it much, but this is reminding me a lot of the media directory symlink issue from Mage 1. stackoverflow.com/questions/21434859/… Also, don't think of it as hacking the core files! We now have the power to make things better, perhaps you can patch the code to handle symlinks and pop in a PR to Magento? Dec 9, 2015 at 21:05
  • 3
    I pointed the relevant internal team at this one as well. There is some related work coming up next sprint, so hopefully we can review and improve as a part of that effort.
    – Alan Kent
    Dec 9, 2015 at 22:16
  • 1
    I bumped into the same thing a few days myself as well. The issue is within the isExists() method which adds the absolute path (of the Magento root) to the relative path, to check whether it exists. There simply should be an extra check that checks whether the relative path is in fact already an absolute path. I will submit a PR for this. Dec 29, 2015 at 17:13
  • You could try to do mount -o bind instead of symlinking.
    – matt
    Mar 2, 2016 at 23:41

2 Answers 2

3

there are still some places in Magento 2, which are not compatible with components outside of Magento root. We're working on fixing them. Thanks for reporting, so we would not miss any such place (this one is already in our list).

Unfortunately, I can't suggest any workaround for it now.

2

Found an ugly, but temporary workaround for the static assets problem. For reasons that aren't 100% clear, for symlinked files Magento will pass an already absolute $path the getAbsolutePath method in the Magento\Framework\Filesystem\Driver\File class

#File: vendor/magento/framework/Filesystem/Driver/File.php
public function getAbsolutePath($basePath, $path, $scheme = null)
{
    return $this->getScheme($scheme) . $basePath . ltrim($this->fixSeparator($path), '/');
}

Since $path is already absolute, this method ends up generating an incorrect absolute path.

My fix is to temporarily hack in some code to detect this situation

public function getAbsolutePath($basePath, $path, $scheme = null)
{
    if(time() > strToTime('2016-01-25'))
    {
        throw new \Exception("Don't forget this hack: " . __FILE__);
    }
    if(strlen($path) > 0 && $path[0] === '/' && file_exists($path) )
    {
        return $path;
    }

    return $this->getScheme($scheme) . $basePath . ltrim($this->fixSeparator($path), '/');
}

The first if clause is something I've started doing with all my temporary hacks to ensure if they somehow end up on an important system, they have a time bomb explosion that will point to them clearly.

The second if clause detects if the method's been passed an already absolute path, and if so returns the correct path (assuming the file actually exists).

Why a hack instead of a plugin? Because it looks like the static asset serving application at pub/static.php does not allow you to plugin to classes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.