2015年4月20日 星期一

用 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");
        }

      });

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

沒有留言 :