主要講述的為:在不修改原有文件(vendor/fancyecommerce下面的所有文件)
的前提下,修改任意功能,fecshop 的重寫詳細如下:
這個屬于Yii2的范疇,一般通過配置的方式更改Yii2的組件(composer) ,譬如:
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=fecshop',
'username' => 'root',
'password' => 'fd#Ed49lpafdfgeaFs2$d',
'charset' => 'utf8',
],
我可以先寫一個php文件繼承yii\db\Connection
,
然后將class
對應的文件指向我自己重寫后的php文件,即可實現重寫該
Yii2組件。相信這個大家基本都知道。
module
是Yii2框架里面的一個概念,
譬如文件:@fecshop/app/appfront/config/modules/Customer.php
文件,即可實現重寫該
return [
'customer' => [
'class' => '\fecshop\app\appfront\modules\Customer\Module',
'params'=> [
'register' => [
# 賬號注冊成功后,是否自動登錄
'successAutoLogin' => true,
# 注冊登錄成功后,跳轉的url
'loginSuccessRedirectUrlKey' => 'customer/account',
# 注冊頁面的驗證碼是否開啟
'registerPageCaptcha' => true,
],
...
],
],
];
上面是模塊的配置,如果你想要重構整個模塊(module),
那么您可以通過上面進行配置class
,指向您重寫的文件。
service的重寫和組件的重寫類似,譬如文件:
@fecshop/config/services/Category.php
文件
return [
'category' => [
'class' => 'fecshop\services\Category',
# 子服務
'childService' => [
'product' => [
'class' => 'fecshop\services\category\Product',
],
'menu' => [
'class' => 'fecshop\services\category\Menu',
//'rootCategoryId' => 0,
],
...
您新建一個class
繼承fecshop\services\Category
,然后在class
指向您新建的文件,在您新建的class做函數
重寫即可。
對于用戶來說想要二開appfront的模板,需要修改才能滿足自己的需求,
但是對fecshop就比較難辦,因為fecshop升級,難免也要修改view css js也要改動
等文件,這些文件不同于php類文件的重寫機制,無法通過繼承重寫函數
的方式進行二開模板文件,
因此就帶來了矛盾沖突,fecshop參考了magento的多模板機制,
設置二開的高優(yōu)先級模板路徑,譬如,fecshop想要找view文件
/category/product/index.php
,首先會在二開模板路徑里面找,如果
找到,就不會使用fecshop的模板路徑下面的/category/product/index.php
因此通過這種方式實現的模板重寫。
fecshop的模板部分,以入口進行區(qū)分(appfront apphtml5等)的同時, 每一個store又是可以單獨選擇模板的。
模板的重寫原理是通過模板路徑優(yōu)先級來,也就是有好幾個 模板路徑,分別為fecshop的模板路徑【低優(yōu)先級】,第三方的模板路徑【中優(yōu)先級】, 用戶二開(二次開發(fā))的模板路徑【高優(yōu)先級】,fecshop的模板路徑的文件最為 全面(優(yōu)先級最低),然后用戶想要重寫某個文件,只需要把這個文件路徑復制到 二開模板路徑下(包括相對文件夾路徑),即可完成重寫,因為 用戶二開模板路徑優(yōu)先級最高。
下面以appfront(pc端)進行舉例 說明:
appfront入口的模板路徑的配置是在:
@fecshop/app/appfront/config/params.php
'appfrontBaseTheme' => '@fecshop/app/appfront/theme/base/front',
也就是默認所有的store都是使用這里的模板,
用戶二開的模板路徑的定義在文件:
appfront/config/fecshop_local_services/Store.php
在每一個store中,您可以看到如下的內容:
'localThemeDir' => '@appfront/theme/terry/theme01', # 設置當前store對應的模板路徑。關于多模板的方面的知識,您可以參看fecshop多模板的知識。
'thirdThemeDir' => [], # 第三方模板路徑,數組,可以多個路徑
@appfront/theme/terry/theme01
: 為本地二開路徑,優(yōu)先級最高
thirdThemeDir
: 第三方插件的模板路徑,如果您安裝了多個第三方
的插件,那么您需要按照順序填寫多個,這里是數組的方式填寫。
重寫模板詳細舉例:
fecshop模板路徑為:@fecshop/app/appfront/theme/base/default
,
我想要重寫這個view文件:
@fecshop/app/appfront/theme/base/default/catalog/category/index.php
我本地store設置的模板路徑為:
appfront/theme/terry/theme01
因此,我創(chuàng)建文件
appfront/theme/terry/theme01/catalog/category/index.php
然后把@fecshop/app/appfront/theme/base/default/catalog/category/index.php
文件的內容復制到@appfront/theme/terry/theme01/catalog/category/index.php
中,然后修改這個文件,就完成了該文件的重寫。
是不是很easy呢?
原理還是有一點小復雜,有興趣可以參看資料:
yii2 多模板路徑優(yōu)先級加載view方式下- js和css 的解決
Yii2本身是有多語言翻譯功能,但是缺少重寫機制,我進行了擴展,
對于fecshop的翻譯,您可以重寫fecshop原有的文件翻譯: (目前后臺是沒有翻譯的),下面以appfront進行舉例:
打開文件:
fecshop/app/appfront/config/appfront.php
您可以看到如下配置:
'components' => [
# language config.
'i18n' => [
'translations' => [
'appfront' => [
//'class' => 'yii\i18n\PhpMessageSource',
'class' => 'fecshop\yii\i18n\PhpMessageSource',
'basePaths' => [
'@fecshop/app/appfront/languages',
],
],
],
],
首先將Yii2 i18n
組件進行了重寫,您可以看到class
改成
了fecshop的class
,另外設置了翻譯文件的路徑 basePaths
。
打開 @fecshop/app/appfront/languages
,您可以看到有很多語言的包,
打開 @fecshop/app/appfront/languages/zh_CN/appfront.php 你就會看到是一個大的配置數組,這里是fecshop的appfront 的原有的配置,下面我們來看重寫的步驟:
打開文件:@appfront/config/main.php
你會看到如下:
'i18n' => [
'translations' => [
'appfront' => [
'basePaths' => [
'@appfront/languages',
],
'sourceLanguage' => 'en_US', # 如果 en_US 也想翻譯,那么可以改成en_XX。
],
],
],
該配置設置了本地翻譯語言的路徑為@appfront/languages
,
并且設置了基礎語言為:en_US
。
然后就可以打開 @appfront/languages/zh_CN/appfront.php
進行重寫
翻譯內容了
注意: 模板的重寫是文件的替換,翻譯文件的重寫是文件內容合并,相當于兩個數組合并(merge)
如果相同的key,本地的翻譯會覆蓋fecshop的翻譯。
不支持:模板部分和翻譯部分
該重寫是通過Yii2的classMap
機制實現的,關于classMap可以參看
類映射表Class Map
我整理的一篇關于classMap的原理文章: 通過配置的方式重寫某個Yii2 文件 或第三方擴展文件
看完了上面的文章,您應該就會明白classMap
是個啥玩意,下面
說一下fecshop中的使用。還是以appfront舉例:
@appfront/config/YiiClassMap.php
文件:
<?php
return [
//'fecshop\app\appfront\helper\test\My' => '@appfront/helper/My.php',
];
在代碼中,我們會通過use加載其他的類,
use fecshop\app\appfront\helper\test\My
,
默認回去找文件 @fecshop/app/appfront/helper/test/My.php
但是如果我在classMap中進行了配置
'fecshop\app\appfront\helper\test\My' => '@appfront/helper/My.php'
,
那么當我在調用My類 use fecshop\app\appfront\helper\test\My
,
use的類就變成了 @appfront/helper/My.php
,而不是@fecshop/app/appfront/helper/test/My.php
,
到這里您應該明白了吧。
對于功能部分,單個文件的修改還是用classMap的方式, 在classMap做文件指向,在重寫后的文件最好也要有一定的規(guī)律,便于 維護,您可以重寫某個Controller,block,model,組件,services,
如果您進行整塊功能替換,譬如重寫某個services,某個modules ,那么就可以通過上面的方式進行。
至此,我們已經可以,在不修改fecshop代碼的前提下,修改 fecshop的任意功能了。
更多建議: