swayok / laravel-site-loader
将单个项目(例如:后台和前端)的几个不同部分(站点)分离的类
Requires
- php: >=5.5
- laravel/framework: >=5.2
- swayok/utils: ~1.0
This package is auto-updated.
Last update: 2024-09-16 23:27:49 UTC
README
例如:你有一个项目,其中包含几个非常不同的站点。比如说 - 这是前端、后台和超级管理员站点。所有这些站点都有不同的资源(视图、CSS、JS、图像等),但使用共同的DB模型、类等。分离它们将是一个糟糕的想法,可能会浪费很多时间。
那么如果我们使用服务提供者呢?
这可以在简单情况下完成。但是,如果您有一些 register() 和 provides() 方法,您将需要手动检测是否需要加载它们,您还需要为 boot() 方法执行相同的验证。当您有对相同 '\Class\Name' 的 '$this->app->singleton('\Class\Name', callback)
' 调用,但具有不同的 'callback
' 时,不使用条件留下这些方法可能是危险的。我遇到了很多问题,最终制作了这些类,以尽可能简单地解决这些问题。
如何使用它
1. 创建站点加载器
为您的项目中的每个站点创建一个扩展 \LaravelSiteLoader\AppSiteLoader
的加载器类。(或者您可以使用 \LaravelSiteLoader\AppSiteLoaderInterface
来创建自己的 \LaravelSiteLoader\AppSiteLoader
版本)
前端
namespace App\Frontend;
use LaravelSiteLoader\AppSiteLoader;
class FrontendSiteLoader extends AppSiteLoader {
static public function canBeUsed() {
return (
$_SERVER['REQUEST_URI'] === '/'
|| empty($_SERVER['REQUEST_URI'])
|| starts_with($_SERVER['REQUEST_URI'], static::getBaseUrl())
);
}
static public function getBaseUrl() {
return '/account';
}
public function boot() {
static::setLocale();
// your code here
}
static public function getDefaultLocale() {
return 'en';
}
public function register() {
// your registrations here
}
public function provides() {
// your privides list here
return [];
}
}
后台
namespace PeskyCMF\CMS\CmsAdmin;
use LaravelSiteLoader\AppSiteLoader;
class AdminSiteLoader extends AppSiteLoader {
static public function getBaseUrl() {
return '/admin';
}
public function boot() {
static::setLocale();
// your code here
}
static public function getDefaultLocale() {
return 'en';
}
public function register() {
// your registrations here
}
public function provides() {
// your privides list here
return [];
}
}
在 \LaravelSiteLoader\AppSiteLoader
中有一些预定义字段
/** @var AppSitesServiceProvider */
protected $provider;
/** @var Application */
protected $app;
和函数
static public function canBeUsed() {
return (
$_SERVER['REQUEST_URI'] === '/'
|| empty($_SERVER['REQUEST_URI'])
|| starts_with($_SERVER['REQUEST_URI'], static::getBaseUrl())
);
}
/**
* @return ParameterBag
*/
protected function getAppConfig() {
return config();
}
/**
* Sets the locale if it exists in the session and also exists in the locales option
*
* @return void
*/
static public function setLocale() {
$locale = session()->get(get_called_class() . '_locale');
\App::setLocale($locale ?: static::getDefaultLocale());
}
/**
* Configure session for current site
* @param string $connection - connection name
* @param int $lifetime - session lifetime in minutes
*/
public function configureSession($connection, $lifetime = 720) {
$config = $this->getAppConfig()->get('session', ['table' => 'sessions', 'cookie' => 'session']);
$this->getAppConfig()->set('session', array_merge($config, [
'table' => $config['table'] . '_' . $connection,
'cookie' => $config['cookie'] . '_' . $connection,
'lifetime' => $lifetime,
'connection' => $connection,
'path' => static::getBaseUrl()
]));
}
如果需要特定内容,请覆盖它们。
2. 创建和配置特殊服务提供者
创建一个扩展 \LaravelSiteLoader\Providers\AppSitesServiceProvider
的单一服务提供者,并包含一些特定配置: protected $defaultSectionLoaderClass
和 protected $sectionLoaderClasses
。我个人使用 AppServiceProvider
来做这个
namespace App\Providers;
use LaravelSiteLoader\Providers\AppSitesServiceProvider;
use App\Frontend\FrontendSiteLoader;
use App\CmsAdmin\AdminSiteLoader;
class AppServiceProvider extends AppSitesServiceProvider {
protected $defaultSectionLoaderClass = FrontendSiteLoader::class;
protected $sectionLoaderClasses = [
AdminSiteLoader::class,
];
}
在这里
protected $defaultSectionLoaderClass
在无法使用protected $sectionLoaderClasses
中的加载器时使用protected $sectionLoaderClasses
是除默认加载器之外的所有站点加载器的列表
为了检测正确的加载器,\LaravelSiteLoader\Providers\AppSitesServiceProvider
为 $this->sectionLoaderClasses
列表中的所有加载器类调用 AdminSiteLoader::canBeUsed()
方法。第一个返回 true 的加载器将被分配给 $this->siteLoader
属性。如果没有匹配的加载器,则将 $this->defaultSectionLoaderClass
加载器分配给 $this->siteLoader
属性,而不调用 canBeUsed()
方法
3. 将您的服务提供者添加到 config/app.php
注意
-
在您的服务提供者中,您可以通过
$this->siteLoader
访问匹配的加载器 -
如果您在服务提供者中覆盖了
boot()
、register()
或provides()
方法,请确保在您的方法中调用parent::boot()
、parent::register()
和parent::provides()
方法,以保存加载器的功能。如果您的服务提供者中重载了 provides() 方法,此代码可能很有用public function provides() { return array_unique(array_merge( parent::provides(), [ \App\Http\Request::class, DbModel::class ] )); }
-
在
\LaravelSiteLoader\Providers\AppSitesServiceProvider
中,我重新声明了一些方法为公共public function loadTranslationsFrom($path, $namespace) public function loadViewsFrom($path, $namespace) public function publishes(array $paths, $group = null)
因此您可以在加载器中使用它们,通过 $this->provider->loadTranslationsFrom('/path', 'namespace')