0

(这个问题与数据库无关。我知道在多租户方面通常会考虑数据库。但这不是我的问题。)

我创建了一个可供不同客户使用的应用程序。他们可以看到并做大部分相同的事情。但是,有些客户在这里和那里有一些额外的按钮,某些功能被禁用或其他一些不同。

我想避免大量的 if/else 或 switch 语句。所以我想我可以为每个客户提供一个通用模块和特殊模块,根据需要覆盖或覆盖不同的东西。看下面的理论结构(所有文件都是正常的 Yii 文件):

app
    general
        controllers
            OrderController
            InvoiceController
            ShippingController
        views
            order
                index, view, update, create, _form
            invoice
                index, view, update, create, _form
            shipping
                index, view, update, create, _form
            layout
                main
        models
            Order
            Invoice
            Shipping
    customerA
        controllers
            OrderController  // some action is different
    customerB
        views
            invoice
                view         // some buttons should be overridden
            layout
                main.php     // other page structure
    customerC
        views
            order
                index        // table gets some additional columns
        model
            Order            // has some more properties
    customerD
        // this customer exists but has nothing that must be changed
        // it uses all what is in general
    ...
web
common
console
...

我认为这是一个合理的文件结构。至少它是清晰易懂的。现在我想以某种方式实现:如果客户请求任何东西,如果有特定客户的文件并使用它们,或者使用通用模块(后备)中的文件,应用程序将首先查看。我的问题是:我该怎么做?

如果可能,怎么做?还是仅部分可能,例如仅使用控制器和视图?我想视图/控制器/模型文件可能需要不同的方法。我想可以调整类自动加载。而且我会考虑使用路由(尽管客户必须经过身份验证,所以它只能使用他或她自己的客户):

http://example.com/customerA/invoice/view?id=1234

所有这些都可以通过配置或依赖注入来完成吗?我需要模块还是文件组织足够?

(想法:覆盖控制器可能很简单。但我认为只有在控制器被覆盖以设置另一个视图路径时才能覆盖视图文件。)

有没有人有解决这个问题的想法?如果这适用于控制器和视图,我会很高兴。但是模型也很好。或者有没有人有其他建议或替代方法?即使您只知道部分解决方案,也请告诉我。

我认为一个令人满意的答案可能会随着时间的推移而发展。但这将有助于其他人找到一个好的解决方案。所以让我们继续努力吧 ;-) ... 或者是另一个框架更适合这个任务?:-(

4

1 回答 1

0

您可以通过如下代码使用单独的主题:

  1. 覆盖 yii\base\Theme
  2. 使用依赖注入来使用您的自定义主题组件
  3. 制作一个空的配置条目以使您的主题组件被调用
  4. 创建/复制您的自定义主题文件

阅读此主题说明

阅读此以获取依赖注入说明(或如何替换其他模型)

此示例显示如何将 ' @app/views' 替换为 ' @app/themes/mytheme'。

common\components\Theme.php(自定义主题组件)

namespace common\components;
use Yii;

class Theme extends \yii\base\Theme 
{

    public function init() {
        // todo: your logic goes here
        $this->pathMap = [
            '@app/views' => [
                '@app/themes/mytheme',
            ]
        ];

        return parent::init();
    }

}

common\extensions\Bootstrap.php(用于 DI 的自定义引导程序)

namespace common\extensions;

use Yii;
use yii\base\Application;
use yii\base\BootstrapInterface;
use yii\helpers\Url;

class Bootstrap implements BootstrapInterface
{
    public function bootstrap($app)
    {
        Yii::$container->set(\yii\base\Theme::className(), \common\components\Theme::className());
    }
}

common\config\main.php(注册自定义引导)

'bootstrap' => [
    'common\extensions\Bootstrap',
],

frontend\config\main.php(注册虚拟主题配置)

'components' => [
    'view' => [
        'theme' => [
            'basePath' => '@app/views',
        ],
    ],
],
于 2017-03-04T12:00:13.797 回答