資訊安全課程地圖系統開發手冊
===
[GIT 連結](https://github.com/monkenWu/securityTutorial)
2019/12/18
:::success
:bookmark: 書籤
[TOC]
:::
# 如何部署
## 環境部署
1. PHP7.2~7.*
* WIN環境
[Windows PHP 環境變數](http://asika.windspeaker.co/post/3491-win-php-cli)
* Ubuntu 或 WSL
[使用 WSL 建置 的LAMP 環境](https://hackmd.io/13AcLcNQStmIeeBkeohbsQ)
3. [Composer](https://getcomposer.org/)
4. PHP 必須啟用 intl 模組
in Ubuntu OS
```
sudo apt-get install php7.2-intl
> Select new config
sudo apt-get install zip unzip php7.2-zip
sudo update-alternatives --config php
> Select PHP7.2 index number
```
## 程式部署
將專案從 github fork 一份到自己的儲存庫後 clone 至本地端,再依下列步驟部屬程式。
1. 取得框架檔案
github 上的程式不含框架本體,所以必須在 clone 至本地端後,使用 Composer 套件管理器下載回來。
至 cmd 或 bash 中,cd 至專案根目錄執行以下指令。
```
composer update
```
2. env檔設定
複製跟目錄下的 env 並且重新命名為 .env 。
移除掉 17 行的 # 並且修改至以下內容。
```php=17
CI_ENVIRONMENT = development
```
移除掉 23 行的 # 並且修改至以下內容。
```php=23
app.baseURL = 'http://localhost:8080/'
```
3. 啟動開發伺服器
至 cmd 或 bash 中,cd 到專案根目錄執行以下指令。
```
php spark serve
```
當畫面出現以下訊息,代表開發伺服器已經部屬完畢,可以開始開發。
```
CodeIgniter development server started on http://localhost:8080
```
執行 Ctrl+C 可以關閉開發伺服器。
## 使用框架或程式庫
- 前端
[樣式基於 bootstrap4](http://bootstrap.hexschool.com/docs/4.0/getting-started/introduction/)
[使用套版 Edubin](https://drive.google.com/file/d/1VxcbczMfVlQHrEB0j_EdpyDjhvpq5qYK/view?usp=sharing
)
- 後端
[使用 codeigniter 4.00](https://codeigniter4.github.io/CodeIgniter4/index.html)
# 程式碼撰寫風格
## 排版
### 換行
#### 1. 索引陣列宣告換行。
```php
//ex1包覆在function內的陣列
array_push($data['data'],[
"key" => $row->key,
"name" => $row->name
]);
//ex2普通宣告
$data = [
"name" => $result->name,
"content" => $result->content,
"feedback" => $result->feedback,
"startDate" => $startTime[0]
];
```
#### 2. 字串過長
依語意結構換行,並且向內縮排。
```php
//ex1
$this->light_datatables->ci->db
->from("user")
->select("SHA1(`user`.`key`)as user_key,
SHA1(`user`.permission_key)as permission_key,
`user`.`name`,
`user`.account,
permission.`name` as permission_name");
//ex2
$buttton = "
<button type='button' onclick='openModal(\"editUser\",\"[extra]\")' class='btn btn-outline-primary functions-btn'>編輯資料</button>
<button type='button' onclick='openModal(\"watchUser\",\"[extra]\")' class='btn btn-outline-info functions-btn'>查閱資料</button>
[extra]
';
```
# 開發規則
## View
View 由 Controllers 進行指向,在 app/view 資料夾中的結構與 URL 指向的名稱相同。
| URL | view 資料夾 | 畫面名稱 |
| -------- | -------- | -------- |
| /course/security | /course/security | 資訊安全概論 |
| /course/design | /course/design | 安全軟體設計概論 |
| /course/programming | /course/programming | 安全程式設計概論 |
| /course/web | /course/web | 安全網頁程式設計 |
| /course/cloud | /course/cloud | 安全雲端程式設計 |
| /course/testing | /course/testing | 軟體安全測試 |
### 課程頁面解析器
在課程( course )中, URL 所指向 view 資料夾的檔案結構是固定的,我們以 /course/web 為例:
```
web
├─index.php
├─article.php
├─book.php
├─moocs.php
└─openSource.php
```
這些檔案所定義的內容,足以產生一個完整的畫面:

> 紅線為載入,綠線為直接影響。
各 PHP 皆會初始化一個陣列,變數的列數影響到畫面呈現的筆數,在製作新頁面時,請複製 web 資料夾內的檔案進行修改,變數的結構不可改變,若結構不同,將會影響到模板解析器產生錯誤的結果。
#### 進入點
畫面與資料的進入點為 index.php 這支檔案:
``` php=0
<?php
/***
* 課程資源
* */
//線上教學與教材
require("moocs.php");
//書籍與電子書
require("book.php");
//實務開源工具
require("openSource.php");
//網路技術文章
require("article.php");
$contentData = [
"moocs" => $moocs,
"book" => $book,
"openSource" => $openSource,
"article" => $article
];
$info = [
"time" => "360 小時",
"amount" => count($moocs)+count($book)+count($openSource)+count($article)
];
$extra = [
[
"title" => "Sonar 微軟開源免費網站檢測工具,測試網站效能、安全性等五大層面",
"url" => "https://free.com.tw/sonar/"
]
];
/***
* 額外資源
* */
$featuresData = [
"info" => $info,
"extra" => $extra
];
/***
* 顯示子課程連結(可選,不宣告則不顯示)
* */
$childData = [
[
"path" => "java",
"name" => "Java 安全設計課程"
]
];
?>
<?= view("basic/coursesPage/index",[
"contentData" =>$contentData,
"featuresData" => $featuresData,
//可選,不宣告則不顯示
"childData" => $childData
])?>
```
1. [5~11] 依序引入外部的設定檔案,它們都會宣告一個與自己檔案名稱相同的陣列變數。
2. [13-18] 串接資料組,這些資料最後會被傳送到模板解析器。
3. [20-38] 宣告課程屬性與額外資源等資料,因為這些資料比較少,所以沒有獨立成外部檔案。
4. [43-48] 若這門課程有子課程的存在,則必須宣告此組陣列,並且在下個步驟進行宣告。若不存在子課程,那麼忽略這個設定即可(即不宣告)。
5. [52-57] 解析設定內容串接畫面,最後的資料將會被傳遞到 view/basic/coursesPage/index這個 PHP 內,它將會依序解析陣列所設定的內容,產生出畫面。
### 路由與子課程
1. 一個 web 課程 URL 如下所示:
> /course/web
2. 若這個 URL 具有子課程,則會有如此表現:
> /course/web/php
3. 上述例子指的是,在 web 課程下會有一個 java 的子課程。
由此可知,子課程的 URL 具有無限延展的特性。
> /course/web/php/class1/...
我們繼續以 /course/web 為例,擁有上述子課程的資料結構如下:
```
web
├─java
│ ├─index.php
│ ├─article.php
│ ├─book.php
│ ├─moocs.php
│ └─openSource.php
├─PHP
│ ├─index.php
│ ├─article.php
│ ├─book.php
│ ├─moocs.php
│ ├─openSource.php
│ └─class1
│ ├─index.php
│ ├─article.php
│ ├─book.php
│ ├─moocs.php
│ └─openSource.php
├─index.php
├─article.php
├─book.php
├─moocs.php
└─openSource.php
```
Controller 會自動搜索子課程是否存在,若不存在則會跳轉畫面到最上層。而新增子課程只需要在原資料夾底下再新增新的資料夾,並且保持著上一節提到的檔案結構,就能動態新增子課程的內容。
#### 進入點
當然,子課程的 index.php 結構上也會有一些不同,以 web/java/index.php 為例:
```PHP=44
<?= view("basic/coursesPage/index",[
"contentData" =>$contentData,
"featuresData" => $featuresData,
//子課程必須定義中文標題
"childName" => "Java 安全設計課程"
])?>
```
我們可以看到,在 48 行新增了子課程的中文名稱。
若是你的子課程也擁有子課程,也可以調用上一節提到的 $childData 連結讓畫面具有連貫性,我們以 web/php/index.php 為例:
```PHP=45
$childData = [
[
"path" => "class1",
"name" => "第一組課程"
]
];
?>
<?= view("basic/coursesPage/index",[
"contentData" =>$contentData,
"featuresData" => $featuresData,
//子課程必須定義中文標題
"childName" => "PHP 安全設計課程",
"childData" => $childData
])?>
```
1. [45~50] 雖然 web/php/index.php 本身是子課程,卻也能再繼續向下延伸,並且調用 $childData 的解析器。
2. [58~59] 當然,子課程的標題定義與 $childData 都必須進行宣告。