如何開發(fā)一個 Notadd 模塊

2018-05-23 11:57 更新

模塊代碼結構請參考項目

https://github.com/notadd/content

模塊將包含如下幾個部分:

  • 模塊注入
  • 路由注入
  • 門面注入
  • CSRF注入

模塊安裝

對于模塊的安裝,目前 Notadd 支持的安裝方式,僅為在 根項目 中對 模塊 進行依賴。

例如,需要安裝模塊 notadd/content ,可以修改根項目的文件 composer.json,參考代碼如下:

{
    "name": "notadd/notadd",
    "description": "The Notadd Framework.",
    "keywords": [
        "notadd",
        "cms",
        "foundation",
        "framework"
    ],
    "homepage": "https://notadd.com",
    "license": "Apache-2.0",
    "type": "project",
    "authors": [
        {
            "name": "twilroad",
            "email": "269044570@qq.com"
        }
    ],
    "autoload": {
        "classmap": [
            "storage/databases"
        ]
    },
    "require": {
        "php": ">=7.0",
        "notadd/content": "0.1.*",
        "wikimedia/composer-merge-plugin": "dev-master"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.0",
        "symfony/css-selector": "3.1.*",
        "symfony/dom-crawler": "3.1.*"
    },
    "config": {
        "preferred-install": "dist"
    },
    "scripts": {
        "post-create-project-cmd": [
            "php notadd key:generate"
        ],
        "post-install-cmd": [
            "Notadd\\Foundation\\Composer\\ComposerScripts::postInstall",
            "php notadd optimize"
        ],
        "post-update-cmd": [
            "Notadd\\Foundation\\Composer\\ComposerScripts::postUpdate",
            "php notadd optimize"
        ]
    },
    "extra": {
        "merge-plugin": {
            "include": [
                "extensions/*/*/composer.json"
            ],
            "recurse": true,
            "replace": false,
            "merge-dev": false
        }
    }
}

更新文件 composer.json 后,執(zhí)行 composer update 即可完成對模塊的安裝。

完整示例代碼,請參考項目 https://github.com/notadd/notadd

目錄結構

目錄結構如下:

## module                                             模塊目錄
    # resources                                      資源目錄
        # translations                               翻譯文件目錄
        # views                                      視圖目錄
    # src                                            源碼目錄
        # ModuleServiceProvider.php                  模塊服務提供者定義文件
    # composer.json                                  Composer 配置文件

一個 Notadd 的模塊,是一個符合 composer 規(guī)范的包,所以,模塊對第三方代碼有依賴時,可以在 composer.json 中的 require 節(jié)點中添加第三方的包。

而作為一個符合 Notadd 模塊定義規(guī)范的包,composer.json 需擁有如下信息:

  • type 必須為 notadd-module
  • require 中必須添加包 notadd/installers

代碼參考如下(來自插件根目錄下的文件 composer.json, 文件中不應該包含 // 的注釋信息,此處僅作為說明)

{
    "name": "notadd/content",
    "description": "Notadd's Content Module.",
    "keywords": [
        "notadd",
        "cms",
        "framework",
        "content"
    ],
    "homepage": "https://notadd.com",
    "license": "Apache-2.0",
    "type": "notadd-module",                                                          // type 必須設置為 notadd-module
    "authors": [
        {
            "name": "Notadd",
            "email": "notadd@ibenchu.com"
        }
    ],
    "require": {
        "php": ">=7.0",
        "notadd/installers": "0.5.*"                                                  // 必須依賴包 notadd/installers
    },
    "autoload": {
        "psr-4": {
            "Notadd\\Content\\": "src/"
        }
    }
}

模塊注入

所謂 模塊注入 ,是 Notadd 在加載模塊的時候,會檢索模塊目錄下的類 ModuleServiceProvider,此類必須命名為 ModuleServiceProvider,且需放在源碼根目錄中,且命名空間必須為 composer.json 的中 autoload 節(jié)點定義的符合 psr-4 規(guī)范的命名空間,否則 Notadd 將不能正確加載模塊!

類 ModuleServiceProvider 的父類必須為 Illuminate\Support\ServiceProvider ,且必須包含 boot 方法。相關服務提供者的概念可以參考 Laravel 文檔。

類 ModuleServiceProvider 的代碼參考如下:



<?php
/**
 * This file is part of Notadd.
 *
 * @author TwilRoad <269044570@qq.com>
 * @copyright (c) 2016, notadd.com
 * @datetime 2016-10-08 17:12
 */
namespace Notadd\Content;


use Illuminate\Events\Dispatcher;
use Illuminate\Support\ServiceProvider;
use Notadd\Content\Listeners\RouteRegister;


/**
 * Class Module.
 */
class ModuleServiceProvider extends ServiceProvider
{
    /**
     * Boot service provider.
     */
    public function boot()
    {
        $this->app->make(Dispatcher::class)->subscribe(RouteRegister::class);                // 訂閱事件 RouteRegister
    }
}

路由注入

由于 Notadd 的路由注入,需要實現(xiàn)事件 RouteRegister,并在事件監(jiān)聽中添加 路由 。

所以,所謂的路由注入,實際是在類 ModuleServiceProvider 實現(xiàn)事件 RouteRegister 的訂閱,并在事件訂閱類中注冊模塊所需要的路由。

類 ModuleServiceProvider 的代碼參考如下:

<?php
/**
 * This file is part of Notadd.
 *
 * @author TwilRoad <269044570@qq.com>
 * @copyright (c) 2016, notadd.com
 * @datetime 2016-10-08 17:12
 */
namespace Notadd\Content;


use Illuminate\Support\ServiceProvider;


/**
 * Class Module.
 */
class ModuleServiceProvider extends ServiceProvider
{
    /**
     * Boot service provider.
     */
    public function boot()
    {
    }
}

事件訂閱類 RouteRegister 的代碼參考如下:

<?php
/**
 * This file is part of Notadd.
 *
 * @author TwilRoad <269044570@qq.com>
 * @copyright (c) 2016, notadd.com
 * @datetime 2016-10-08 18:30
 */
namespace Notadd\Content\Listeners;


use Notadd\Content\Controllers\Api\Article\ArticleController as ArticleApiController;
use Notadd\Foundation\Routing\Abstracts\RouteRegistrar as AbstractRouteRegistrar;


/**
 * Class RouteRegister.
 */
class RouteRegister extends AbstractRouteRegistrar
{
    /**
     * Handle Route Registrar.
     */
    public function handle()
    {
        $this->router->group(['middleware' => ['cross', 'web']], function () {               // 路由的注冊
            $this->router->group(['prefix' => 'api/article'], function () {
                $this->router->post('find', ArticleApiController::class . '@find');
                $this->router->post('fetch', ArticleApiController::class . '@fetch');
            });
        });
    }
}

門面注入

門面,是 Laravel 的一個功能特色,可以通過門面調(diào)用對應 IoC 容器的實例,所以 Notadd 必然會保留這一功能。

所謂的路由注入,實際是在類 ModuleServiceProvider 實現(xiàn)事件 FacadeRegister 的訂閱,并在事件訂閱類中注冊模塊所需要的路由。

類 ModuleServiceProvider 的代碼參考如下:

<?php
/**
 * This file is part of Notadd.
 *
 * @author TwilRoad <269044570@qq.com>
 * @copyright (c) 2016, notadd.com
 * @datetime 2016-10-08 17:12
 */
namespace Notadd\Content;


use Illuminate\Events\Dispatcher;
use Illuminate\Support\ServiceProvider;
use Notadd\Content\Listeners\FacadeRegister;


/**
 * Class Module.
 */
class ModuleServiceProvider extends ServiceProvider
{
    /**
     * Boot service provider.
     */
    public function boot()
    {
        $this->app->make(Dispatcher::class)->subscribe(FacadeRegister::class);
    }
}

事件訂閱類 FacadeRegister 的代碼參考如下:

<?php
/**
 * This file is part of Notadd.
 *
 * @author TwilRoad <269044570@qq.com>
 * @copyright (c) 2017, notadd.com
 * @datetime 2017-01-22 12:20
 */
namespace Notadd\Content\Listeners;


use Notadd\Foundation\Event\Abstracts\EventSubscriber;
use Notadd\Foundation\Facades\FacadeRegister as FacadeRegisterEvent;


/**
 * Class FacadeRegister.
 */
class FacadeRegister extends EventSubscriber
{
    /**
     * Name of event.
     *
     * @throws \Exception
     * @return string|object
     */
    protected function getEvent()
    {
        return FacadeRegisterEvent::class;
    }


    /**
     * Event handler.
     *
     * @param $event
     */
    public function handle(FacadeRegisterEvent $event)
    {
        $event->register('Log', 'Illuminate\Support\Facades\Log');
    }
}

CSRF注入

所謂的CSRF注入,實際是在類 ModuleServiceProvider 實現(xiàn)事件 CsrfTokenRegister 的訂閱,并在事件訂閱類中注冊模塊所需要的路由。

類 ModuleServiceProvider 的代碼參考如下:

<?php
/**
 * This file is part of Notadd.
 *
 * @author TwilRoad <269044570@qq.com>
 * @copyright (c) 2016, notadd.com
 * @datetime 2016-10-08 17:12
 */
namespace Notadd\Content;


use Illuminate\Events\Dispatcher;
use Illuminate\Support\ServiceProvider;
use Notadd\Content\Listeners\CsrfTokenRegister;


/**
 * Class Module.
 */
class ModuleServiceProvider extends ServiceProvider
{
    /**
     * Boot service provider.
     */
    public function boot()
    {
        $this->app->make(Dispatcher::class)->subscribe(CsrfTokenRegister::class);
    }
}

事件訂閱類 CsrfTokenRegister 的代碼參考如下:

<?php
/**
 * This file is part of Notadd.
 *
 * @author TwilRoad <269044570@qq.com>
 * @copyright (c) 2017, notadd.com
 * @datetime 2017-02-10 11:04
 */
namespace Notadd\Content\Listeners;


use Notadd\Foundation\Event\Abstracts\EventSubscriber;
use Notadd\Foundation\Http\Events\CsrfTokenRegister as CsrfTokenRegisterEvent;


/**
 * Class CsrfTokenRegister.
 */
class CsrfTokenRegister extends EventSubscriber
{
    /**
     * Name of event.
     *
     * @throws \Exception
     * @return string|object
     */
    protected function getEvent()
    {
        return CsrfTokenRegisterEvent::class;
    }


    /**
     * Register excepts.
     *
     * @param $event
     */
    public function handle(CsrfTokenRegisterEvent $event)
    {
        $event->registerExcept('api/article*');
        $event->registerExcept('api/category*');
        $event->registerExcept('api/content*');
        $event->registerExcept('api/page*');
    }
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號