我想在cakephp 3中创建供应商包。它应该依赖于另一个包,包含php文件和一些静态资产:如js,css,img等。设置php文件自动加载我能够处理。但是要加载来自其他供应商的静态文件,例如
echo $this->Html->css('AnotherPackage.styles');
cake希望它们应该在供应商的webroot
目录中,而不是
# another package's files
/vendor/author/another-package/php
/vendor/author/another-package/css_files
/vendor/author/another-package/js_files
/vendor/author/another-package/images
我发现的类似问题只有copying files to webroot,这是我不想做的事情。
如何告诉蛋糕从其确切的文件夹而不是webroot加载供应商的文件?或者以更好的方式解决这个问题,而不必复制某些东西。我正在使用作曲家。
由于
答案 0 :(得分:0)
您是否正在Linux机器上执行此操作?如果是这样,您可以只创建一个符号链接,以使webroot目录指向软件包的根目录。
答案 1 :(得分:0)
您在使用作曲家吗? 您正在处理的项目是否取决于composer.json文件中供应商的软件包? 如果是这样,您可以在项目中创建一个Controller(类似于ExternalAssets),该Controller可以读取这些供应商文件,并将它们传递给Response对象。
<?php
/**
* ExternalAssetsController
*/
namespace App\Controller;
use App\Controller\Controller\AppController;
use Cake\Core\App;
use Cake\Http\Exception\BadRequestException;
use Cake\Http\Exception\ForbiddenException;
use Cake\Routing\Router;
/**
* ExternalAssets Controller
*
* Serves up external assets that aren't in the webroot folder.
*/
class ExternalAssetsController extends AppController
{
/**
* Initialize method.
*
* @return void
*/
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
// see https://book.cakephp.org/3.0/en/development/routing.html#routing-file-extensions
// or whatever extensions you need.
Router::extensions(['css', 'js', 'png', 'jpg']);
// if you're using the auth component in a restricted way.
$authAllowedActions = ['asset'];
$this->Auth->allow($authAllowedActions);
}
/**
* Delivers an asset.
*
* @param string|null $folder The Folder's name.
* @param string|null $file The File's name.
* @return \Cake\Http\Response
* @throws \Cake\Http\Exception\BadRequestException When $folder or $file isn't set.
* @throws \Cake\Http\Exception\ForbiddenException When we can't read the file.
*/
public function asset($folder = null, $file = null)
{
if (!$folder) {
throw new BadRequestException(__('Folder was not defined'));
}
if (!$file) {
throw new BadRequestException(__('File was not defined'));
}
$folder = str_replace('..', '', $folder);
$file = str_replace('..', '', $file);
$basepath = realpath(ROOT . DS . 'vendor' . DS . 'author' . DS . 'another-package');
$path = realpath(ROOT . DS . 'vendor' . DS . 'author' . DS . 'another-package' . DS . $folder . DS . $file . '.' . $this->getRequest()->getParam('_ext'));
if (strpos($path, $basepath) === false) {
throw new ForbiddenException(__('Path out of bounds, possible hack attempt.'));
}
if (!is_readable($path)) {
throw new ForbiddenException(__('Unable to read the file.'));
}
$this->setResponse($this->getResponse()->withFile($path, [
'name' => $file . '.' . $this->getRequest()->getParam('_ext'),
'download' => false
]));
return $this->getResponse();
}
}
然后使用Router::url()
创建到控制器的编译路径。
像这样:
<link rel="stylesheet" href="<?=Router::url([
'prefix' => false,
'plugin' => false, // unless the controller in in a plugin
'controller' => 'ExternalAssets'
'action' => 'asset'
0 => 'css_files',
1 => 'css_file_name',
'_ext' => 'css'
]) ?>">