Magento/Zend not allowing symbolic links

2019-01-24 14:17发布

问题:

Anyone know why Magento won't allow symbolic links for template .phtml files that are outside the app/design folder?

If I do a symlink within that folder, it works fine, but if it's linked outside that, it doesn't work. So it seems like it's some permissions/security thing, but I can't find any info anywhere.

Possibly a Zend setting? http://zend-framework-community.634137.n4.nabble.com/Zend-Tool-not-working-with-symbolic-links-in-include-path-td662569.html

Anyone?

WORKAROUND: Thanks to Alan's suggestion below I found a workaround - as I'll only be using this myself for local development I'm happy enough. In case this helps anyone else, I'm gonna add it here. So I'm inserting the following in core/Mage/Core/Block/Template.php, directly after the line Varien_Profiler::start($fileName);

    $storeId = Mage::app()->getStore()->getId();
    $theme = Mage::getStoreConfig('design/package/name', $storeId);
    Mage::Log($this->_viewDir.DS.$fileName); 
    $includes = $this->_viewDir.DS.$fileName; 
    if(strpos($includes, 'frontend/'.$theme )) { 
         include $this->_viewDir.DS.$fileName;
        };

Using the IF statement here stops any base templates being doubled, and only allows your custom theme templates through.

回答1:

As of Magento 1.5.1.0 (maybe 1.5.x?) there is an option at System > Configuration > Developer > Template Settings > Allow Symlinks that you can enable.

No need for dirty hacks/workarounds anymore. :-)



回答2:

This was caused by a change in 1.4.2 where Magento no longer allows symlinked folders. If you look in Template.php

        $includeFilePath = realpath($this->_viewDir . DS . $fileName);
        if (strpos($includeFilePath, realpath($this->_viewDir)) === 0) {
            include $includeFilePath;
        } else {
            Mage::log('Not valid template file:'.$fileName, Zend_Log::CRIT, null, null, true);

        }

you see that it won't load if the template is not under the "viewDir".



回答3:

found another nice little solution which works for me:

sshfs 192.168.1.12:/srv/www/vhosts/dev.****.*****.de/media/catalog/product/ catalog/product/ -o allow_other

this mounts the remote file system via sshfs, allow_other option is necesarry to make the files mounted from the remote box without the remote box file rights:

This option will allow you to use -o allow_other in your SSHFS command which will allow your non-root user access to the specific resource you're mounting.

hope this helps to anyone of you



回答4:

I am also using symlinks to my custom code and I managed to overcome this issue by using mount --bind instead of creating symlinks, e.g. custom theme directory: /home/user/workspace/magento/app/design/frontend/default/mytheme

cd <magento dir>/app/design/frontend/default
mkdir mytheme
sudo mount --bind /home/user/workspace/magento/app/design/frontend/default/mytheme mytheme

This method will not work on OSX.



回答5:

Add some logging code to the base template block

#File: app/code/core/Mage/Core/Block/Template.php
public function fetchView($fileName)
{
    ...
    Mage::Log($this->_viewDir.DS.$fileName); 
    var_dump($this->_viewDir.DS.$fileName);
    include $this->_viewDir.DS.$fileName;
    ...
}

Ultimately, rendering a template block is a call to include with a system path. Once you get the path Magento is constructing to your template, create a one line PHP file

<?php
include('/path/that/was/logged/foo.phtml');

And attempt to load the template. This should allow you to isolate the reason any particular call to include is failing. My immediate guess is a PHP safe mode setting, but it's been a long time since I had to fight shared hosting restrictions.

Good luck!