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 

可這一切都可以用配置或依賴注入做了什麼?我需要模塊還是文件組織足夠?

(思考:重寫控制器可以是簡單的,但我認爲這種觀點文件只能在控制器被重寫,以設置另一種看法路徑被覆蓋。)

沒有人有想法解決這個?我會很高興,如果這與控制器和意見。但模型也會很好。還是有人有其他建議或替代方法?即使您只知道部分解決方案,也請告訴我。

我假設一個令人滿意的答案可能隨着時間而變化。但是,其他人找到一個好的解決方案會很有幫助。所以我們來研究一下;-)或者是另一個更適合這個任務的框架? :-(

回答

0

你可以通過這樣的代碼使用單獨的主題:

  1. 覆蓋警予\基地\主題
  2. 使用依賴injenction使用您的自定義 主題分量
  3. 創建一個空的配置項讓你的主題 組件被調用
  4. 製作/複製您的自定義主題文件

read this for theming instructions

read this for dependency injection instructions(或如何更換其他型號)

這個例子展示瞭如何通過 '@app/themes/mytheme' 替換 '@app/views'。

共同\組件\ 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(); 
    } 

} 

共同\擴展\ 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()); 
    } 
} 

共同\設置\ main.php(註冊自定義自舉)

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

前端\設置\ main.php(寄存器虛設主題配置)

'components' => [ 
    'view' => [ 
     'theme' => [ 
      'basePath' => '@app/views', 
     ], 
    ], 
],