# Laminas框架-協作筆記 ###### tags: `Laminas` ### Route - URL 架構 ![](https://i.imgur.com/t1c27e6.png) - 路由設定 > 請在專案的 module/config/module.config.php 設定 - 基本架構設定 ``` '<route_name>' => [ 'type' => '<route_type_class>', 'priority' => <priority>, 'options' => [ 'route' => '<route>', 'defaults' => [ //... ], ], ] ``` - 基本架構設定實例 > URL : *http://主機名/Module名稱/* > 因 **Module名稱** 後面沒有帶任何路徑,所以會讀取 **defaults**的內容,且 **action** 是讀取Controller裡的 ***updateData()*** ``` 'module-example' => [ 'type' => Literal::class, 'options' => [ 'route' => '/module-example', 'defaults' => [ 'module' => 'module-example', 'controller' => Controller\IndexController::class, 'action' => 'updateData', ], ] ] ``` - 含子路由架構設定 ``` '<route_name>' => [ 'type' => '<route_type_class>', 'priority' => <priority>, 'options' => [ //... ], 'child_routes' => [ // Add child routes here. // ... ] ] ``` - 含子路由架構設定實例 > - 以下路由規則為通則,可設計狀況去改變路由設定 > - URL : http://主機名/Module名稱/[控制器名稱/Action名稱/參數] > - URL內的 **"[]"** 代表可帶或可不帶入路徑,則 ***childroutes*** 內容則是定義子路由的內容 > - 如沒帶入任何子路由(或者只帶Controller名稱),則會讀取 ***"option/defaults"*** 內的 Action 內容 > - 因 **Module名稱** 後面可以帶任何路徑片段,所以會讀取 **child_routes**的內容,但 **controller**、**action**、**id** 是則依路徑片段讀取對應的專案內src資料夾內的Controller,及該Controller內的Action或Id等參數。 > - 控制器名稱通常會在定義一個別名,實際帶入URL則為該別名 (定義內容下則說明) > - 子路由設定內容的 ***"option/constraints"*** 則是設定 **controller**、**action** 的命名規則 ``` 'module-example' => [ 'type' => Literal::class, 'options' => [ 'route' => '/module-example', 'defaults' => [ 'module' => 'module-example', 'controller' => Controller\IndexController::class, 'action' => 'updateData', ], ], 'may_terminate' => true, 'child_routes' => [ 'default' => [ 'type' => Segment::class, 'options' => [ 'route' => '[/:controller][/:action][/:id]', 'constraints' => [ 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*' ], 'defaults' => [] ] ] ] ] ``` - Controller設定實例 > - ***aliases*** 內則是設定控制器的別名 > - 如有新增加的controller依序往下增加,則路由位置為: http://主機名/Module名稱/new-one/[Action名稱/參數] ``` 'controllers' => [ 'factories' => [ Controller\IndexController::class => BaseFactory::class, Controller\NewOneController::class => BaseFactory::class, ], 'aliases' => [ 'sign-up-index' => Controller\IndexController::class, 'new-one' => Controller\NewOneController::class, ] ] ``` ### 資料庫處理 #### 資料表規劃、比對、更新 - 規劃好關聯式資料表後,需更新本地專案的 ***"db/db.mwb"*** 到遠端 對應的目錄 - 在遠端執行檔案輸出,並下載更新的Entity到本地對應的位置且覆蓋 > - Entity位置 : 專案/data/temp/更新的Entity > - 指令 : sudo docker exec -ti "容器名稱" bin/export.sh - 複製本地更新的Entity檔案到本地的 ***"專案/Base/src/Entity"*** 內並覆蓋 - 遠端比對資料庫: > - 指令 : sudo docker exec -ti "容器名稱" bin/cli.sh migrations:diff > - 會在遠端的 ***"data/migrations"*** 產生一個新的版本檔案,如下圖: > ![](https://i.imgur.com/168HpM4.png) - 遠端資料庫寫入: > - 指令 : sudo docker exec -ti "容器名稱" bin/cli.sh migrations:migrate > - ![](https://i.imgur.com/UQsWQud.png) ## Doctrine ORM ### CRUD 功能實作說明 > - 以 "share-doc" 專案的 "course-demo" 分支內容做為案例參考 > - 建議專案 git clone 下來後,改名成新的專案,方便作參考比對 > - 實作目標是建立公告欄,對應的資料表為 ***"News"***,此Module會新增兩種功能頁面: **公告欄的列表** 、 **公告欄的留言新增/編輯頁面** > - 權限等級有兩種 : ### 資料表更新 - 請先實作 **"資料庫處理"** 步驟,並確認需新增或修改的資料表已更新! ### 新增Module的初始設定 - 專案的新增Module設定 > - 此設定檔案為: *專案/config/modules.config.php* > - 新增 ***"News"*** 字串至 ***return*** 的內容內 > ![](https://i.imgur.com/1Kzs8nA.png) - autoload的內容新增 > - 此設定檔案為: *專案/compose.json* > - 新增 ***"News\\": "module/News/src/"*** 字串至 ***autoload/psr-4*** 的內容內 > - 新增完後需更新遠端的compose設定,請在終端機執行指令 "***sudo dokcer exec -ti share-docphp1 composer dump-autoload***",更新設定 > ![](https://i.imgur.com/zZFKxqu.png) ### Module架構建置 - 建置一個 ***"News"*** 的Module,架構如下: > - 目前為空架構,加上一些Module的設定檔案,可從其他Module的對應檔案複製到此專案內 > - 需複製的基本設定檔案 : ***"專案/config/module.config.php"***、 ***"專案/src/Module.php"*** > ![](https://i.imgur.com/GyTEi9l.png) - Module設定更改如下: > - ***"module.config.php"***: > 命名空間、路由(Route)相關、控制器(Controller)的設定 > ![](https://i.imgur.com/soddl85.png) > > - ***"module.config.php"***: > 只需改命名空間即可,其他請先用預設即可 > ![](https://i.imgur.com/1CCSWRY.png) ### Controller與View的新增 - Controller的新增 > - 新增架構如下 : > - 新增兩功能所需的Controller > ![](https://i.imgur.com/wpNShnE.png) > - 每個空的Controller的基本寫法 > ![](https://i.imgur.com/2YrCh8z.png) - View的新增 > - 新增架構如下 : > - 因Module新增兩個controller、所以需再新增兩個對應的子資料夾 : ***admin*** 、***index*** > - 預計新增 ***action*** 的關係對應請參考下圖 > ![](https://i.imgur.com/RRdHiuY.png) > - 每個view檔案(twig格式)的內容請如下圖新增即可: > ![](https://i.imgur.com/jmC6amO.png) ### ACL的設定(權限設定) - acl.global.php 設定 - 修改檔案位置 > ***"專案/config/autoload/acl.global.php"*** > - 現有系統角色 > 目前只會用到 **"系統管理員"** 、 **"訪客"** 兩角色 > ![](https://i.imgur.com/PLqjdRK.png) - 資源設定 > 需為這兩角色設定可以讀取的資源,設定如下圖說明 > ![](https://i.imgur.com/hHzjQym.png) ### 取消登入認證的cache(測試環境) - 全域變數設定 - 修改檔案位置 > ***"專案/config/autoload/global.php"*** - 新增"is_cached"參數,並設為false > ![](https://i.imgur.com/OOpUEmg.png) - 登入認證取消Cache - 登入是由 ***"專案/module/User/src/Controller/SignController.php"*** 執行 - 實際修改檔案位置 > ***"專案/module/Base/src/Controller/Plugin/AclPlugin.php"*** - 取消Cache > 在doAuthorization() 內加上以下判斷,請參考下圖 > ![](https://i.imgur.com/NHfIMGP.png) ### 訪客訪問頁的實作 - 撰寫 ***IndexController.php*** > 檔案位置 : ***專案/module/News/src/Controller*** 內 - 需引入相關所需套件、命名空間需正確 - 登入者資訊需正確登入才能取得 - 將資料置入到需回傳的ViewModel物件 ![](https://i.imgur.com/E9Bd5f9.png) - 撰寫 ***index.twig*** > 檔案位置 : ***專案/module/News/view/news/index*** 內 - 透過twing語法,寫入繼承的view框架 - 透過twing語法,印出從Controller取得的資料 ![](https://i.imgur.com/x32eHWM.png) ### 公佈欄列表頁的實作 - 撰寫 ***AdminController.php*** > 檔案位置 : ***專案/module/News/src/Controller*** 內 - *indexAction()* 實作內容 : 列表資料存取-邏輯處理 > ![](https://i.imgur.com/Pt6oD4L.png) - 撰寫 ***index.twig*** > 檔案位置 : ***專案/module/News/view/news/admin*** 內 - 透過twing語法,寫入繼承的view框架 - 在這個view內建立表單及印出從Controller取得的data資料 > ![](https://i.imgur.com/f1i1oxF.png) - 在inline 區塊內,寫入編輯、刪除按鈕的點擊觸發事件 > ![](https://i.imgur.com/bn6DIEI.png) ### 公佈欄編輯的實作 - 撰寫 ***NewsForm.php*** > 檔案位置 : ***專案/module/News/src/Form*** 內 > 為 ***edit.twig*** 內會使用的Form表單的設定皆在此 > - 先新增以下資料夾與檔案 > ![](https://i.imgur.com/Ylm7heO.png) > - 在 ***"NewsForm.php"*** 內先建立好建構式等,並建議從MySQL Workbranch 內 EER Diagram 複製 SQL出來並貼上到程式內參考 > ![](https://i.imgur.com/TAwa8NF.png) > - 在建構式內建立與表單標籤對應的方法,請參考下圖方式 > - 並在建構式外建立一個表單過濾的相關方法: ***"addInputFilter()"*** > ※相關官方文件參考 : [Form Element](https://docs.laminas.dev/laminas-form/element/element/) > ※相關官方文件參考 : [Inputfilter](https://docs.laminas.dev/laminas-inputfilter/intro/) > ![](https://i.imgur.com/uwfDGjt.png) - 撰寫 ***AdminController.php*** > 檔案位置 : ***專案/module/News/src/Controller*** 內 > - *updateAction()* 實作內容 : 編輯公告欄資料-邏輯處理 > (待編輯...) - *deleteAction()* 實作內容 : 刪除公告欄資料-邏輯處理 > (待編輯...) - 撰寫 ***edit.twig*** > 檔案位置 : ***專案/module/News/view/news/admin*** 內 > (待編輯...) #### 參考連結 > 用法A:QueryBuilder > [Query](https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/dql-doctrine-query-language.html) > 用法B:Entity > [Entity](https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/query-builder.html)