2015年5月1日 星期五

Sapodilla 人心果

上周日去市集時, 在舊鎮公所前面的路邊跟一位婆婆買薑時, 看見地上擺了一籃這種小時候常吃的水果, 一斤 40 元, 我就買了兩斤回味回味. 很奇怪, 到了5字頭這年紀對童年會特別有感覺.

這水果小時候聽大人稱其為 "沙波基拉", 聽起來像是日語名稱, 好像是日據時代日本人從南洋引進的. 味道很甜, 吃起來沙沙的, 似有土味, 既像柿子, 又像水梨.  記得以前住在台糖鐵路邊的堂伯公後院就有一棵這種果樹, 祖母帶我串門子時, 伯婆就會請我吃.

買回來後三四天就全熟了, 菁菁與二哥吃後覺得尚可接受, 說味道像柿餅. 姊姊就說得很難聽, 說甚麼味道像柿子放在流理台出水口一周後的味道 (姊姊, 妳是吃過喔? 不能憑空想像啦). 種子是扁扁黑色的, 整個看來與奇異果很像, 只是沒毛而已 :


切開後發現果肉是綠褐色, 大約有四個種子 :


今天早上上班時把剩下的兩顆帶到辦公室請同事吃, 最重要的是要問看看有沒有人知道這水果的名稱. 蔡樣一看就說似乎是人心果, 或者人參果. 上網一查果然是人心果沒錯, 參考 :

# wiki : 人心果
# 認識植物--人心果
# 人心果
# 一個人與花草的生活 : 人心果

另外, 根據這篇 :

# 人心果的功效与作用

原來人心果營養價值很高, 特別是 :
  1. 含鈣量 910mg/100g, 是紅柿的 114 倍
  2. 維他命 C 130mg/100g, 是蘋果與水梨的 32 倍
  3. 富含抗癌成分硒與鉬
這樣好的水果賣相與口感卻不佳, 可見上帝是公平的. 我個人是覺得, 因葡萄糖含量高, 這種甜度如果拿來釀酒應該不錯, 既然當水果接受度不高, 釀成酒應該可以改頭換面, 脫胎換骨了吧! 留下種子試種看看.


2015年4月28日 星期二

第 18 周記事

這個周日的下午因小舅, 婷婷, 阿娟, 以及高樹阿姨來訪, 顯得非常熱鬧. 小舅媽巡菜園時看見我年前一周種的第一批玉米, 說可以採收了, 否則會太老. 我還想說下周再採呢. 扳開玉米尖端一看, 果然米粒飽滿, 當下採收十支, 剩下七八支的留給晚到的婷婷採. 洗淨後立刻下鍋水煮, 其甜味果然如書中所言, 在兩小時內煮來吃, 又新鮮又甜美.


上週五爸去看阿蘭時, 發現腳浮腫, 護理師說排尿不順, 要去醫院掛診. 中午醫生來電說因插尿管不易, 建議做膀胱造口, 並住院幾日觀察. 我想才去養護中心住三周, 竟然變成這樣, 這也不能怪養護中心, 可能阿蘭以前沒有包尿布習慣所致. 週末回鄉下時去病房看她, 與養護中心其他住院的老婆婆同間, 似乎也不會吵鬧, 看到我們頗為高興. 但為防止她拔管針, 手被護士綁起來, 無法滑我的手機. 週日去看她時, 剛好醫師值班, 我問了原因, 他也無法給個明確的答案, 說可能是年紀大了, 排尿不順. 對此我頗為自責, 是否當初應該請外勞才對? 但因請外勞挺麻煩, 母親生前也不認同, 我離退休還很久, 故衡量後決定到機構安置.

過去這一周我又重新回來寫程式專案, 除了搞定 Appfog 的上傳問題外, 也修正了一些 Bug, 新增了部分功能.


2015年4月24日 星期五

無法登入 GAE 問題

今天在處理 GAE 的 cron 問題時, 在命令提示字元視窗下 :

appcfg.py --no_cookies download_app -A myapp -V 1 e:\gae\myapp

輸入 gmail 與密碼後卻發現無法登入 :

11:38 AM Host: appengine.google.com
####################################################
OAuth2 is now the recommended authentication method.
Use the --oauth2 flag to enable.
####################################################
11:39 AM Fetching file list...
Email: myaccount@gmail.com
Password for myaccount@gmail.com:
Invalid username or password.

確定密碼沒錯,試了好幾次還是不行. 由於這帳號是爸的 gmail, 沒有申請兩階段驗證, 應該用 gmail 原本的密碼就行. 兩階段的要另外產生, 參考 :

# 開啟兩階段認證後手機無法使用 Google 服務問題

我到 google 帳戶去找線索, 發現在帳戶設定的 "安全性較低的應用程式存取權限" 是 "已封鎖" :


點一下已封鎖就可以選擇將其打開 :




經過這樣改變設定後, 就可以順利登入 GAE 後台了. 完成後為了安全起見再把它改回已封鎖.

今天一口氣將所有已經不用的 CRON 全部關掉, 只留驅動 Appfog 的兩個應用程式的帳號與 hello, mybidbot 兩個驅動器.


2015年4月23日 星期四

GAE 後台管理指令集

今天終於把三月初暫停的 000a.biz 專案程式大致回復了, 這給我一個教訓, 要定時備份系統, 不要以為跑得順順的就不理它, 一旦系統無法運轉, 裡面寶貴的程式與資料若無法拿回來就虧大了. 那可是花了不少時間寫出來的啊.

這次的麻煩主要是我忽略 000a.biz 要求升級的來信, 我認為那只是行銷而已, 不予理會, 結果四月十日果真就被停止後台使用權了, 這麼巧,  Inhon 筆電就在同一天無法啟動, 必須從光碟做系統回復. 這樣一來本機伺服器在 C:\ AppServ\www 下的程式檔都消失了, 而 TF 卡中的程式雖還在, 但可能不是最新的. 幸好 000a.biz 同意我取回程式的要求, 這幾天就是忙比對取回的程式與 TF 卡中備份的程式有何差異. 沒有做好資料保全的下場就是這樣, 浪費寶貴的時間.

程式檔回復後上傳 Appfog, 接下來就是 GAE 驅動程式的部分了. 先到 GAE 申請一個新的應用程式專案, 然後把之前給驅動 000a.biz 的應用程式複製一份, 作如下修改 :
  1. main.py : 把原 000a.biz 的 URL 為 Appfog URL.
  2. app.yaml : 把第一行的 application 名稱改為新應用程式名稱 
  3. default.htm : 把標題改為 Appfog 應用程式名稱
這樣就可以上傳了. 但使用 GAE SDK Launcher 才發現, SDK 已升版到 1.9.19 了, 所以上 GAE 網站更新了 SDK :

# https://cloud.google.com/appengine/downloads

更新完上傳應用程式卻出現如下訊息 :

2015-04-23 17:03:24 Running command: "['C:\\Python27\\pythonw.exe', '-u', 'C:\\Program Files (x86)\\Google\\google_appengine\\appcfg.py', '--oauth2', 'update', u'E:\\GAE\\appfog-myAPP']"
05:03 PM Application: appfog-myAPP; version: 1
05:03 PM Host: appengine.google.com
05:03 PM
Starting update of app: appfog-myAPP, version: 1
05:03 PM Getting current resource limits.
2015-04-23 17:03:35,434 WARNING old_run.py:88 This function, oauth2client.tools.run(), and the use of the gflags library are deprecated and will be removed in a future version of the library. 
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&response_type=code&client_id=xxxxxxxxx.apps.googleusercontent.com&access_type=offline

If your browser is on a different machine then exit and re-run
this application with the command-line parameter

  --noauth_local_webserver

有問題了, 但沒時間研究, 乾脆改用 command line 來上傳吧. 以下是 appcfg 常用的指令集 :
  1. 上傳應用程式 :
    appcfg.py update APPNAME
  2. 更新 CRON :
    appcfg.py update_cron APPNAME
  3. 顯示 CRON :
    appcfg.py cron_info APPNAME
  4. 下載應用程式 :
    appcfg.py download_app -A APPNAME -V 1 DIRNAME
上傳結果如下 :

E:\GAE>appcfg.py update appfog-myAPP
07:28 PM Application: appfog-myAPP; version: 1
07:28 PM Host: appengine.google.com
####################################################
OAuth2 is now the recommended authentication method.
Use the --oauth2 flag to enable.
####################################################
07:28 PM
Starting update of app: appfog-myAPP, version: 1
07:28 PM Getting current resource limits.
Email: tony123@gmail.com
Password for tony123@gmail.com:
07:29 PM Scanning files on local disk.
07:29 PM Cloning 1 static file.
07:29 PM Cloning 9 application files.
07:29 PM Compilation starting.
07:29 PM Compilation completed.
07:29 PM Starting deployment.
07:29 PM Checking if deployment succeeded.
07:29 PM Deployment successful.
07:29 PM Checking if updated app version is serving.
07:29 PM Completed update of app: appfog-myAPP, version: 1
07:29 PM Uploading index definitions.
07:29 PM Uploading cron entries.

跑了近四小時, 觀察對 Appfog 發出的 Request 蠻正常, 完全 0 error, 可見 Appfog 主機真的一級棒, 難怪收費比人家貴, 還好我有留下免費帳戶, 雖然容量與流量有受限制, 但作為實驗性網站也夠了 :


哈哈, 系統又重新跑起來了, 估計後天全部資料就會抓完全了, 但要謹記這次的教訓, 定期備份系統.

接下來要把目前已經沒用到的 GAE cron table 停掉, 只留兩個 Appfog 帳號以及慢速測試用的 0000webhost 驅動器即可.

參考 :

# 停止 GAE 的 cron jobs 的方法
# 下載備份 Google App Engine 應用程式檔案的方法
# Uploading, Downloading, and Managing a Python App


2015年4月22日 星期三

用 jQuery EasyUI 打造輕量級 CMS (十二) : Pclzip 壓縮解壓縮

今天突發奇想, 既然 Appfog 不提供 web 介面來管理檔案上傳與下載, 何不自己寫一個呢? 其實我不需要實作 cPanel 那種完整的檔案與目錄管理, 只要下列三個功能即可 :
  1. 將整個根目錄下全系統備份為 zip 檔下載
  2. 刪除全部資料
  3. 上傳 zip 檔自動解壓縮覆蓋原系統
首先去官網下載 :

# Pclzip 官方網站 (Pclzip 下載)

解開後將其中的 pclzip.lib.php 複製到 EasyUICMS 專案目錄下的 lib 下, 然後於系統檔 sys.php 前面增加匯入此函式庫 :

require_once("lib/pclzip.lib.php");  //匯入zip/unzip模組     (選項)

不過接下來要在哪裡放置這個系統更新與備份下載功能按鈕就費思量了. 因為昨日測試發現已安裝 af 的 Ruby 免安裝版可以移到其他電腦使用, 所以利用 Pclzip 來自行打造系統更新備份功能的計畫暫緩, 以後有需要再進行.

關於 Pclzip 的用法請參考 :

# AJAXPLORER:超強大的 PHP + AJAX 開源文件管理系統
# PHP解壓縮和製作壓縮 (使用pclzip)
# php 解壓縮zip 使用pclzip
# PHP CONTENT : PclZip Overview


2015年4月21日 星期二

Appfog 雲端主機 Client 端安裝問題解決辦法

上個禮拜為了在我的應宏筆電安裝 Appfog 的 Client 花了很多時間仍然徒勞無功, 即使照以前安裝 Ruby 1.9.3 的方法也不行 :

# Appfog 雲端虛擬主機

我發現 Appfog 有改變其 Client 安裝方式, 以前是只要安裝好 Ruby 1.9.3 或 2.0.0 後, 直接下 gem install af 即可; 但現在根據其官網說明, 卻必須下載安裝 Devkit 開發工具, 然後再用 gem install af 安裝 Client, 但問題就出在這裡, 經過回鄉下用 Win 7 甚至 XP 電腦測試, 不論安裝哪一個 Ruby 版本, 都會出現 extension error 而無法成功 :

# Appfog 雲端開發環境新作法

最後決定算了, 要更新系統時再用 AOD D260 小筆電上傳即可.

今天突發奇想, Ruby 也提供 zip 檔, 讓無管理權限安裝程式者也可以使用 Ruby, 那我何不將 AOD D260 小筆電裡面可以用的 Ruby 2.0.0 版從 C:\Program Files 下複製出來, 放到應宏筆電中執行看看? 結果真的可以, 真是太棒了, 這樣就可以用免安裝軟體方式執行了.

我把 Ruby 2.0.0 壓縮為 zip 放在下面 :

# 下載免安裝 Ruby 2.0.0 (已安裝 Appfog Client af)

注意, 下載解壓縮後放在硬碟下, 然後切到 bin 目錄下, 複製其位址, 例如 E:\Ruby200\bin, 將其增加到 "控制台/系統/進階系統設定/環境變數" 中的 Path 內, 開啟命令提示字元視窗下 path 指令確定路徑設定沒問題 :

Microsoft Windows [版本 6.3.9600]
(c) 2013 Microsoft Corporation. 著作權所有,並保留一切權利。

C:\Users\Tony Huang>path
PATH=C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Clien
t\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\W
indowsPowerShell\v1.0\;C:\Program Files\Intel\Intel(R) Management Engine Compone
nts\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Prog
ram Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files
 (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Ja
va\jdk1.7.0_71\bin;C:\Program Files (x86)\Java\jdk1.7.0_71\db\bin;C:\Program Fil
es (x86)\Java\jdk1.7.0_71\jre\lib;c:\python27;c:\python27\scripts;C:\Program Fil
es\Bandizip\7z;C:\Program Files (x86)\Google\google_appengine\;C:\AppServ\Apache
2.2\bin;C:\AppServ\php5;C:\AppServ\MySQL\bin;E:\Ruby200\bin

重開命令提示字元視窗, 再下 af -v 就可以看到 af 的版本是 0.3.18.12 :

C:\Users\Tony Huang>af -v
[WARNING] DL is deprecated, please use Fiddle
af 0.3.18.12


C:\Users\Tony Huang>af login
[WARNING] DL is deprecated, please use Fiddle
Attempting login to [https://api.appfog.com]
Email: tony123@gmail.com
Password: ********
Successfully logged into [https://api.appfog.com]

這樣就登入 Appfog 後台了, 切換到本機的專案目錄下, 用 af update app-name 指令來更新系統 :

E:\mysnowball>af update mysnowball
[WARNING] DL is deprecated, please use Fiddle
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (37K): OK
Push Status: OK
Stopping Application 'mysnowball': OK
Staging Application 'mysnowball': OK
Starting Application 'mysnowball': OK

E:\mysnowball>

早一點想到這招免安裝版的話, 就不用浪費這麼多時間了.


架設風力發電機 part2

週日 (4/19) 下午小舅回去後, 想起我的風力發電機底座還沒安裝好, 於是找出上兩周油漆好的底板, 放到角鐵支架上, 正揣摩要如何鎖螺絲時, 才發現板子上竟有一隻小蟲 :


附近則有兩三個洞 : 


卡好, 難道是蛀蟲嗎? 我叫爸來看, 他說這是白蟻, 會把整塊木板掏空, 二話不說就捏死了這隻白蟻. 有可能這塊購自特力屋的板子已經有白蟻, 上油漆後它受不了就跑出來了. 

把塗上藍色漆的底板用四顆螺絲鎖在角鐵支架上, 然後再鋸一塊固定板,  塗上油漆 (只剩紅色), 用螺旋螺絲鎖在底板上, 最後將發電機用一個環形鐵箍鎖在固定板上.  這固定板方向對著風向最強的西南方, 因為每天下午總是會有強烈的西南風吹過來. 下面是安裝後的測視圖 :


底下是後視圖 :


超過啟動風速後即開始發電 :



拿了電表來量, 發電電壓於風力強勁時可達 50V, 經過電壓調整器後對 12V 鉛酸電池充電應該沒問題. 因為還沒有想好怎樣幫發電機遮雨, 而接下來幾天氣候不穩定, 所以先將發電機拆下來, 下周再來想解決辦法 :


紅色的固定板尺寸 : 長 16cm, 寬 14.5cm, 厚 1.5cm. 是要蓋個小木屋呢? 還是拿個不要用的飯盒蓋上去呢? 或者用上回買的珍珠板組一個方盒? 真是傷腦筋. 

成本概算 :

發電機含葉片 450
基座角鐵 170
螺絲螺帽組 50
基座木板 60

目前小計 730 元.

參考 :

# 大灣高中-廢棄吊扇改直立風力發電機

小舅媽的蠔油冬粉

週日 (4/19) 小舅媽回鄉下, 中午教我煮了這道菜, 其實這是她去餐廳吃過後, 觀察其材料內容, 回來後揣摩出來的, 我也常常用這種方法學做菜. 此道菜所需材料如下 :
  1. 高麗菜半顆
  2. 芹菜一把
  3. 火鍋肉片一盒
  4. 冬粉若干捲
  5. 花椒一小包
  6. 香菜一把
  7. 素蠔油
作法如下  :

高麗菜切小片, 芹菜與香菜切小段備用. 熱鍋加一匙油, 放入花椒炒香後加入2~3 碗水與 2~3 匙醬油, 水滾過後用篩撈起花椒粒, 鋪上一半的火鍋肉片, 高麗菜與芹菜, 疊上冬粉, 最上面再鋪上剩下的一半高麗菜與芹菜, 肉片與香菜, 淋上適量素蠔油, 蓋上鍋蓋以中火燜煮, 約十分鐘後打開來翻炒, 若水分已被吸乾, 再加些水繼續燜煮至肉片與菜全熟即可.


我非常喜歡冬粉, 只要自助餐有上這道必點. 而舅媽這道蠔油冬粉尤為美味, 我想是因為透著花椒的香氣之故. 下次要自己來做看看, 特記下作法以免遺忘.


2015年4月20日 星期一

第 16 周記事

這個周末有自知之明, 沒帶多少書回鄉下, 因為通常沒多少時間看. 反正週日早上行程就是去大阿姨家巡視, 買菜, 慈恩塔上香, 養護中心看阿蘭, 然後回家煮中餐. 整個早上就去掉了, 只剩下午可做整理菜園等雜事而已. 回鄉下就拋開書跟電腦, 純粹做事就好.

周日除了早上摘些杓菜與地瓜葉給大阿姨有到菜園外, 沒有在菜園勞動. 不過茄子已經開花結果, 支架我已立好,  等長高一些再來綁繩子固定 :


第一批玉米的鬚已經開始變褐色, 可能兩周之後就可以採收了 :


第二批也已經開花 :


同事給我的木瓜樹上個月被野狗折斷, 令我惋惜, 沒想到竟然重新長出嫩葉了 : 


可能是上周拿菜去給有緣哥, 這周他拿來一包自製的南瓜饅頭, 同時從菜園拔走一把蔥, 原來那畦青蔥是他去年夏天種的, 那時媽常叫他有空時來種菜. 而媽自己種的是下面這三株, 下周回去再分株擴大 :


本周雖然時間不多, 但事情倒是完成不少.  下午在小舅幫忙下, 先將梳妝鏡安裝在新建浴室, 然後把二樓浴室的磁性門檔裝上去. 傍晚再將前兩周沒完成的發電機底座安裝作業完成.


用 jQuery EasyUI 打造輕量級 CMS (十一)

睽違一個多月沒動這個專案了, 這兩三天因為 000a.biz 停止了我的應用程式, 無奈之下只好另擇良木而棲. 還好 000z.biz 有把程式跟資料庫還我, 所以我將這兩天自行修改部分與 000a.biz 還我的程式做個混合調整, 修改了部分EasyUICMS 系統與 STOCK 專案程式, 由近而遠摘要如下.

今天將調整後的專案 ZIP 檔上傳以前用過的 000webhost 這一家虛擬主機商, 結果系統安裝後竟然沒有出現成功訊息視窗, 我研判應該是 Ajax 回傳訊息有問題, 用 F12 觀察 Response 發現, 果然回傳訊息後面還帶了 000webhost 的統計用 Javascript :

{"status":"success","msg":"MySQL \u8cc7\u6599\u5eab\u53c3\u6578 : <br>MYSQL_ADDRESS=mysql3.000webhost.com<br>........."}
<!-- Hosting24 Analytics Code -->
<script type="text/javascript" src="http://stats.hosting24.com/count.php"></script>
<!-- End Of Analytics Code -->

而 index.htm 的 Ajax 回傳訊息處理如下 :

      $("#install_form").form({
        url:"install.php",
        method:"post",
        success:function(data){
          var data=eval('(' + data + ')');
          $("#install_dialog").dialog("close");
          if (data.status==="success") {  //不會符合
            $.messager.alert("訊息",data.msg,"",function(btn){
              if (btn){window.location.href="index.php";}
              else {window.location.href="index.php";}
              });          
            }
          else {
            $.messager.alert("訊息",data.msg,"info",function(btn){
              if (btn){window.location.href="index.php";}
              else {window.location.href="index.php";}
              });          
            }        
          }
        });

這樣用 eval() 把 data 轉成物件時就會失敗, 以至於雖然安裝成功了 (可由 phpMyAdmin 觀察資料表都正常建立得知), 但卻沒有顯示成功訊息. 我用 substr 擷取回傳訊息中的 {} 部分解決 :

          var r=data.substr(0,data.indexOf("}") + 1); //取出 {} 部分字串
          var data=eval('(' + r + ')');  //轉成物件

所以以後處理 Ajax 回傳異常時, 不要以為自己的程式有錯, 要馬上想到免費主機大都會在回傳訊息後面安插統計資訊, 使 Ajax 回傳處理函式破功, 這在本機 localhost 以及某些免費主機 (如以前免費的 Appfog) 都不會有這問題. 事實上不只是在 index.htm 裡有此 Ajax 回應被加上額外訊息導致的錯誤, 在 sys.php 中也有同樣的問題, 甚至應用程式 STOCK.php 也是, 所以都一併修改了.

其次我修改了系統程式 sys.php 裡的 remove_app 模組, 添加移除應用程式在網頁左方導覽列中所建立的超連結 :

        //找出屬於此 APP 的導覽區塊
        $RS=search("sys_nav_blocks","app",$app_name);
        for ($i=0; $i          $block_id=$RS[$i]["id"];
          //從 sys_nav_links 刪除此 app 所建立之超連結
          $result=delete_record("sys_nav_links","block_id",$block_id);
          if ($result===FALSE) {
            $status="failure";
            $msg .= "刪除應用程式在 sys_nav_links 之超連結失敗
";
            }
          }
        //從 sys_nav_blocks 刪除此 app 所建立之超連結
        $result=delete_record("sys_nav_blocks","app",$app_name);
        if ($result===FALSE) {
          $status="failure";
          $msg .= "刪除應用程式在 sys_nav_blocks 之超連結失敗
";
          }

當移除應用程式時, 會先找出資料表 sys_nav_blocks 中屬於該應用程式的導覽區塊找出來, 然後到 sys_nav_links 資料表中刪除該區塊的所有連結. 最後刪除 sys_nav_blocks 中該應用程式的導覽區塊. 當然, 為了配合這個功能, 在安裝程式 install.php 中, 建立 sys_nav_blocks 資料表時, 要添加 app 欄位 :

    //插入 sys_nav_blocks 之連結
    $data_array["title"]="主功能";
    $data_array["sequence"]=0;  
    $data_array["display"]="Y";  
    $data_array["app"]="varchar(255)";         //所屬應用程式名稱
    $result=insert("sys_nav_blocks", $data_array);
    $data_array=NULL;

另外, sys.php 程式中的 nav_blocks, list_nav_blocks, add_nav_block, update_nav_block 這四個模組也要為了這個新增的 app 欄位添加程式碼.

最後在應用程式的安裝檔, 例如 STOCK_install.php 裡面, 要建立導覽區塊時, 務必在 sys_nav_blocks 資料表的 app 欄位指定應用程式名稱, 例如下面是為 STOCK 應用程式建立 STOCK 與 BROKER 這兩個導覽區塊 :

//插入 sys_nav_blocks 之連結
$data_array["title"]="STOCK";
$data_array["sequence"]=2;  
$data_array["display"]="Y";  
$data_array["app"]="STOCK";  
$result=insert("sys_nav_blocks", $data_array);
$data_array=NULL;
$RS=search("sys_nav_blocks","title","STOCK");
$nav_block_1=$RS[0]["id"]; //sys_nav_links 用

//插入 sys_nav_blocks 之連結
$data_array["title"]="BROKER";
$data_array["sequence"]=3;  
$data_array["display"]="Y";  
$data_array["app"]="STOCK";  
$result=insert("sys_nav_blocks", $data_array);
$data_array=NULL;
$RS=search("sys_nav_blocks","title","BROKER");
$nav_block_2=$RS[0]["id"]; //sys_nav_links 用

//插入 sys_nav_links 之連結
$data_array["title"]="台股觀測站";            
$data_array["url"]="https://2330.tw/";                
$data_array["target"]="_blank";
$data_array["sequence"]=0;
$data_array["block_id"]=$nav_block_1;
$data_array["hint"]="台股觀測站";
$result=insert("sys_nav_links", $data_array);

$data_array=NULL;

另外, 為了佈署在 Appfog, 又把 index.htm 中原本已拿掉的 Appfog 專用安裝程式碼放回去 (因為 Appfog 的 MySQL 參數必須用環境參數 VCAP_SERVICES 取得後再用 $mysql_config[] 讀取) :

  //先判斷是否為 Appfog 雲端虛擬主機以讀取 MySQL 連線參數
  $services_json=json_decode(getenv("VCAP_SERVICES"),true);
  if (is_array($services_json)) { //appfog 雲端虛擬主機
      $mysql_config=$services_json["mysql-5.1"][0]["credentials"];
      $username=$mysql_config["username"];
      $password=$mysql_config["password"];
      $hostname=$mysql_config["hostname"];
      $port=$mysql_config["port"];
      $address="$hostname:$port";
      $db=$mysql_config["name"];
      } //end of if
  else { //一般 PHP+MySQL 虛擬主機 (從 dbsettings.php 檔讀取)
    $str=read_file("db.php"); //讀取資料庫設定檔初始值 (或參考值)
    $username=return_between($str,"'MYSQL_USERNAME','","')","EXCL");
    $password=return_between($str,"'MYSQL_PASSWORD','","')","EXCL");
    $address=return_between($str,"'MYSQL_ADDRESS','","')","EXCL");
    $db=return_between($str,"'DATABASE','","')","EXCL");
    } //end of else

最後修改了檔案上傳功能的一個 Bug, 
 在 sys.php 的 files 模組增添表單 validate 功能, 否則若檔案說明沒填, 上傳會當在那邊沒有回應 :

    $("#upload_file_go").bind("click",function(){
      var arr=$("#uploader").filebox("getText").split("\\");
      filename=arr[arr.length-1];
      var reg=/^[a-zA-Z0-9._-]+$/g;
      if (reg.test(filename) && $("#upload_file_form").form("validate")) {
        $("#uploading").css("visibility","visible");
        $("#upload_file_form").form("submit");    
        }
      else {
        var msg="每一欄位均須填寫! 檔名必須為英數字, 小數點, 底線, " +
                "或減號之組合! 請更改檔名!<br>";
        $.messager.alert("訊息",msg,"warning");
        }

      });

以上便是此次意料之外的大改版, 沒想到換個虛擬主機竟然發現這麼多需要修改的地方.