2018-06-23 12:04:33 2203次浏览 1条回答 0 悬赏 10 金钱

资源文件会动态发布到 web/assets 文件夹,能不能动态上传到文件服务器发布呢?如阿里云的OSS,是不是可能通过自定义(扩展)assetManager 来实现?如果已有相关的扩展就更好了。
下面是我找到的Yii1的,有没有谁可以提供Yii2的,找不到就只能自己写了!

class S3AssetManager extends CAssetManager
{

    public $bucket;
    public $path;
    public $host;
    public $s3Component = 's3';
    public $cacheComponent = 'cache';
    private $_baseUrl;
    private $_basePath;
    private $_published;

    public function getBasePath()
    {
        if ($this->_basePath === null)
        {
            $this->_basePath = $this->path;
        }
        return $this->_basePath;
    }

    public function getBaseUrl()
    {
        if ($this->_baseUrl === null)
        {
            $this->_baseUrl = 'http://'.$this->host.'/'.$this->path;
        }
        return $this->_baseUrl;
    }

    private function getCache()
    {
        if (!Yii::app()->{$this->cacheComponent})
            throw new CException('You need to configure a cache storage or set the variable cacheComponent');

        return Yii::app()->{$this->cacheComponent};
    }

    private function getS3()
    {
        if (!Yii::app()->{$this->s3Component})
        	throw new CException('You need to configure the S3 component or set the variable s3Component properly');
        return Yii::app()->{$this->s3Component};
    }

    private function getCacheKey($path)
    {
        return $this->hash(Yii::app()->request->serverName).'.'.$path;
    }

    public function publish($path, $hashByName=false, $level=-1, $forceCopy=false)
    {
        if (isset($this->_published[$path]))
            return $this->_published[$path];
        else if (($src = realpath($path)) !== false)
        {
            if (is_file($src))
            {
                $dir = $this->hash($hashByName ? basename($src) : dirname($src).filemtime($src));
                $fileName = basename($src);
                $dstDir = $this->getBasePath().'/'.$dir;
                $dstFile = $dstDir.'/'.$fileName;
                if ($this->getCache()->get($this->getCacheKey($path)) === false)
                {
                    if ($this->getS3()->putObjectFile($src, $this->bucket, $dstFile, $acl = S3::ACL_PUBLIC_READ))
                    {
                        $this->getCache()->set($this->getCacheKey($path), true, 0, new CFileCacheDependency($src));
                    }
                    else
                    {
                        throw new CException('Could not send asset do S3');
                    }
                }

                return $this->_published[$path] = $this->getBaseUrl()."/$dir/$fileName";
            }
            else if (is_dir($src))
            {
                $dir = $this->hash($hashByName ? basename($src) : $src.filemtime($src));
                $dstDir = $this->getBasePath().DIRECTORY_SEPARATOR.$dir;

                if ($this->getCache()->get($this->getCacheKey($path)) === false)
                {
                    $files = CFileHelper::findFiles($src, array(
                            'exclude' => $this->excludeFiles,
                            'level' => $level,
                            )
                    );

                    foreach ($files as $f)
                    {
                        $dstFile = $this->getBasePath().'/'.$dir.'/'.str_replace($src.DIRECTORY_SEPARATOR, "", $f);

                        if (!$this->getS3()->putObjectFile($f, $this->bucket, $dstFile, $acl = S3::ACL_PUBLIC_READ))
                        {
                            throw new CException('Could not send assets do S3');
                        }
                    }

                    $this->getCache()->set($this->getCacheKey($path), true, 0, new CDirectoryCacheDependency($src));
                }


                return $this->_published[$path] = $this->getBaseUrl().'/'.$dir;
            }
        }
        throw new CException(Yii::t('yii', 'The asset "{asset}" to be published does not exist.', array('{asset}' => $path)));
    }

}
  • 回答于 2018-06-23 13:40 举报

    可以把source 设置为null
    css ,js文件直接写你的oss文件地址就行

    class BootstrapAsset extends \yii\web\AssetBundle
    {
        public $sourcePath =null ;
        public $css = [
            '//oss.xxx.com/css/bootstrap.min.css',
            '//oss.xxx.com/css/bootstrap-theme.min.css',
        ];
        public $js=[
            '//oss.xxx.com/js/bootstrap.min.js',
        ];
    }
    

    视图引用:

    BootstrapAsset::register(this);
    
    2 条回复
    回复于 2018-06-28 08:20 回复

    这个是设置为OSS,需要手动上传,没有实现动态的目的。

    回复于 2018-06-28 08:41 回复

    对,要实现动态的话,要重写 AssetManager 下的publish相关方法了

    觉得很赞
您需要登录后才可以回答。登录 | 立即注册
阿刚
见习主管

阿刚 深圳

注册时间:2016-04-04
最后登录:2024-02-22
在线时长:15小时6分
  • 粉丝4
  • 金钱185
  • 威望0
  • 积分335

热门问题