Etable/開發

出自六年制學程
跳轉到: 導覽搜尋

main()中函式分布地圖

待補完註解

  1. 已登入檢查細緻到換頁時檢查群組或個人是否有效。新增 $_SESSION['tableName']
  2. et.js 的作用

待實作

  1. 連動表單,須資料表有代名才會動,應修改掉
  2. 處理 javascrip 函式在 theme 中的 html1 與 login::js() 與 etable.php 中同名重複的問題。
  3. 抵禦注入式攻繫
  4. 表單輸入資料時,可以接受特殊的中文字,請參考聶小倩文
  5. ccess/showComment.php 嵌入 openWithSelfMain(在et.js中定義) 的一般化
  6. search 增加:like、等於、包含於等指示

PHP是否允許已在的類別或物件再增添新方法,待查。

可參考混成

工作程式

出 $html1,$html2 的條件判斷

  1. 只要沒有引用 login.php 或 etable.php 就直接出,免條件判斷。如下面的(一)和(三)。
  2. 也可以使用 ajax 更新畫面,不靠翻頁。此時要找一個靠 ajax 傳遞的變數來判斷不用重刷畫面。如下面的(二)。
  3. !isset($_REQUEST['exec_type']) 條件是給有登入或使用 etable 的工作程式用的,只要 exec_type 沒了,就重刷新頁,同時重做 theme 和「登出」鈕。如下面的(四)和(五)。
  4. 可以穿透諸 site 的 /webContent.php ,任何時候 theme 都不重刷,不用出 $html1,$html2 。如下面的(六)。

(一)免登入,未使用資料庫(預設連資料庫,不管工作程式須不須要)

<?php
include_once 'userConstant.php' 或 'constant.php';	// 載入伺服器參數
include_once 'theme.php';				// 載入 site 布景,順便會載入 site 常、變數,連資料庫
$str=…;
echo $html1;
echo $str;
echo $html2;
?>

(二)使用 ajax 更新畫面,不靠翻頁

<?php
include_once 'userConstant.php' 或 'constant.php';
include_once 'theme.php';
include CLASS_FILE_PATH.'/database/login.php';	// 只用 login::js() ,不使用 login()
if(!isset($_REQUEST['某個透過ajax傳送的變數'])){echo $html1.login::js();}
…
if(!isset($_REQUEST['某個透過ajax傳送的變數'])){echo $html2;}
?>

(三)免登入,使用資料庫(預設連資料庫,不管工作程式須不須要)

<?php
include_once 'userConstant.php' 或 'constant.php';
include_once 'theme.php';	// 載入 site 布景,順便會載入 site 常、變數,連資料庫
$result=DB::queryF("…");
$str=…;
while($row=mysqli_fetch_assoc($result)){$str.=…;}
echo $html1;
echo $str;
echo $html2;
?>

(四)登入而不使用etable,須要判別 exec_type ,以避免反復出「登出」鈕

<?php
include_once 'userConstant.php' 或 'constant.php';
include_once 'theme.php';	// 載入 site 布景,順便會載入 site 常、變數,連資料庫
if(!isset($_REQUEST['exec_type'])){echo $html1;}	// 本行須在 theme.php 與 $login->logon(); 之間
include_once CLASS_FILE_PATH."/database/login.php";
$login = new login;
$login->errPrompt="<br/><span style='color:red;'>僅允許………</span>";
$login->loginTable=array('tableName'=>'認證表','name'=>'帳號欄','psd'=>'密碼欄','grp'=>'群組欄','canWorkGrp'=>'通過群組');
$login->logon();
if(isset($login->checkin) && $login->checkin==1){$str=…;}
echo $str;
if(!isset($_REQUEST['exec_type'])){echo $html2;}
?>

(五)使用 etable ,是否登入不影響結構。須要判別 exec_type ,以避免反復出 theme

<?php
include 'userConstant.php' 或 'constant.php';
include 'theme.php';
if(!isset($_REQUEST['exec_type'])){echo $html1;}	// 本行須在 theme.php 與 $ET->main(); 之間
include CLASS_FILE_PATH.'/database/etable.php';
$ET = new etable;
$ET->errPrompt=…;	// 本行在須登入時才出現
$ET->loginTable=…;	// 本行在須登入時才出現
$ET->sql[0]="…";
$ET->main();
if(!isset($_REQUEST['exec_type'])){echo $html2;}
?>

(六)用 webContent 表中的內容穿透各種不同的 theme

全伺服器共用:

  1. webContent 資料表,其中可穿透諸 site 的內容 path 長這樣「/webContent.php/頁名」,其他的頁名都會帶其隸屬的 site 。
  2. webContent.js:造 javascript 的 webContent 函式。
  3. webContent.php,能適應諸 site 的通用欄值映射程式:
<?php
include_once './constant.php';
include_once CLASS_FILE_PATH."/database/DB.php";
require_once(CLASS_FILE_PATH."/database/etloc_ct.php");
$dsnConnection=DB::connect(DSN);
echo webContent($_SERVER['REQUEST_URI']);	// 由 constant.php 載入 GfWebContent.php 所定義
?>

工作程式(通常是 theme.php):

"<script language = 'javascript' src='/webContent.js' ></script>
<a href='' onClick=\"webContent('/webContent.php/頁名?ajax=1','div的ID');return false;\">◎◎◎◎◎</a>"

使用由工作程式定義之函數

batch

  • batch屬性為陣列,每一元素之索引為按鈕提示,每一元素之名函式名。
  • 諸函式在前置處理時執行。
  • 範例:
    1. $物件->sql[0]="select 數欄,concat('<input type=text name="ba[',id欄,'][表單欄1]" value="',表單欄1,'" >') 欄代名,concat('<input type=text name="ba[',id欄,'][表單欄2]" value="',表單欄2,'" >') 欄代名 from 諸表 where 條件";
    2. $物件->batch=array('按鈕提示'=>'函式名');
    3. 添函式:
function 函式名(){
	if(isset($_REQUEST['ba'])){
		foreach($_REQUEST['ba'] as $k=>$v){
			$up_sql="update 表 set";
			$up_col=array();
			foreach($v as $kk=>$vv){
				if($vv!=''){$up_col[]="`".$kk."`='".etable::quoteSmart($vv,'-addslashes')."'";}// MySQL處理欄值會去反斜,所以先加反斜
				else{$up_col[]="`".$kk."`=''";}
			}
			$up_sql.=implode(",",$up_col)." where id欄='".$k."'";
			mysql_query($up_sql);
		}
		echo '寫好了';
	}
}

banE(允許有權限者編或刪)

  • 範例:
    1. 設 $物件->banE='函式名';
    2. 添函式:
function 函式名($row){
	if(!in_array($_SESSION['login_user'],explode(';',$row[幾]))){
		$row['banEdit']=1;
		$row['banErase']=1;
	}
	return $row;
}

傳入函式的 $row 其實是由 $ET->sql[0] 中 select 指令所造成的陣列,而 $row[幾] 指示的是 select 之後的哪一欄,其欄值以「;」分開幾個人名,其中如果有登入者就指示該筆資料可以出現編連結或刪連結。

以函式決定欄值的表現

  • 在工作程式中對 formType 增加一元素 '長欄名'=>array('function',函式名)
  • 定義函式,傳回值用來取代該欄的欄值並顯示於輸出。
  • 範例:
    1. 設 $物件->formType=array('長欄名'=>array('function',函式名));
    2. 添函式:
function 函式名($arr){
	if($arr['row'][3]==$_SESSION['login_user']){return $arr['value'];}
	else{return '無權看';}
}

對編刪連結產生限制 banE

  • 在工作程式中定義一個判別函式 xxx($row) ,引數為 $row 並使用 $_SESSION ,return 回來含兩個變數 $row['banEdit'],$row['banErase'] 的新 $row 。
  • 增添 $物件->banE='函式名' ,函式名指的是上項的那個函式,如 'xxx' 。
  • 在 etable.php 的 mk_rows 方法中,加入「if(isset($this->banE) && $this->banE){$temp=$this->banE;$row=$temp($row);}」,然後將 $row 放入 $this->tbl 。
  • 各種顯示方法共用「編、刪連結生成函式 up_links($row)」,其中會由 $row['banEdit'],$row['banErase'] 的值判斷要不要抑制編、刪連結連結。

求欄值

etable.php 中的 function colValue(欄序,$value,$row) 以欄序逐一處理。

  1. text欄或bolb欄
    • 欄值為二進位內容,並不秀出內容,而是秀出提示
    • 若formType指示為 'auto' 欄,並包含使用 wiki 語法,顯示$wiki->wiki2html($value)
    • flag未帶binary或演算式者為text欄,進一步判讀是否為HTML格式
  2. 若formType指示為 'unix_time' 欄,則依格式指示顯示
  3. 若formType指示為 'oneWaySwitch' 欄,則秀按鈕
  4. 若為連動選單的第二選單:秀提示或'------'
  5. 若formType指示為 'function' 欄,取出函式名,執行函式,引數為 $arr ,秀函式傳回值。
    $arr['colOrder'] 為「欄序」
    $arr['value'] 為「欄值」
    $arr['row'] 為「欄值陣列」,即 $arr['row'][0] 為第一欄欄值, $arr['row'][1] 為第二欄欄值,餘類推
  6. 交代要轉成提示者:
    • 排除'unix_time' 欄
    • 若formType指示為 'select' 或 'select2' 或 'radio' 欄,依欄值秀出相應提示。
    • 若formType指示為 'radioyn' 欄,依欄值真假秀出相應提示。
    • 若formType指示為 'checkbox' 欄,依欄值秀出相應提示。
    • 若formType指示為 'wrap' 欄,$value中的「;」代換為換行<br/>
  7. 轉換數學公式 mimetex($value)

欄位種類

派值範例:
  $formType=array('長欄名'=>array('select',array('值'=>'提示文字','值'=>'提示文字','值'=>'提示文字',…)),
                  '長欄名'=>array('select2',第一選單陣列,第二選單長欄名,第二選單二維陣列,第二選單以提示代表欄值),
                  '長欄名'=>array('select22',array(0=>'===請選擇===')),
                  '長欄名'=>array('radio' ,array('值'=>'提示文字','值'=>'提示文字','值'=>'提示文字',…)),
                  '長欄名'=>array('radioyn',array('0之提示','1之提示')),
                  '長欄名'=>array('checkbox',array('勾選後送值'=>'提示')),
                  '長欄名'=>array('checkbox',array('勾選後送值'=>'提示','勾選後送值'=>'提示','勾選後送值'=>'提示',…)),
                  '長欄名'=>array('bitCheckbox',array('1'=>'提示','2'=>'提示','4'=>'提示',…)),
                  '長欄名'=>array('date'),改畢,因欄值'%Y-%m-%d'是小日曆認得的格式,所以預選日期為欄值日期
                  '長欄名'=>array('time'),
                  '長欄名'=>array('datetime'),
                  '長欄名'=>array('auto',array('plain','html','wiki','tex')),改畢,$this->formType中未定義,則$this->fields[$i]['formType']會自動將該欄定為auto型,如欄型為TEXT則form出textarea,其他出文字欄。第二元素為語法組合陣列,預設為plain(純文本),要wiki型,欄型須為TEXT,該改。
                  '長欄名'=>array('auto',array('plain','html','wiki','tex'),array('showColExplain'=>'填寫提示')),
                  '長欄名'=>array('text',array('showColExplain'=>'填寫提示')),
                  '長欄名'=>array('rangeNumber',array('min'=>'下限值','max'=>'上限值','step'=>'步進值','showColValueGuide'=>'函式名')),
                  '長欄名'=>array('file',array('docsPath'=>文件根目錄,'paths'=>可選的路徑陣列,'showColValueGuide'=>'函式名')),
                  '長欄名'=>array('hidden',函式名,表單元素出現時機),
                  '長欄名'=>array('unix_time','Y-m-d<bR>H:i:s',表單元素出現時機),待改,因欄值'%s'是小日曆不認得的格式,所以預選日期為跑到當天日期,要認得欄值格式須為「年-月-日 [10] 時:分」,用Calendar.setDateFormat('%s');無效。此事無解,參看http://192.168.3.175/et/class/calendar/jstest.htm,不是每一種格式jscalendar都可以認得出日期,如Date #0:的%s會解不出日期,Date #2:的…會解錯日期,Date #4:解不出日期。
                  '長欄名'=>array('oneWaySwitch',array(0=>'按鈕字',值=>'按完字')),
                  '長欄名'=>array('searchSelect',array(''=>'===輸入提示===')),
                  '長欄名'=>array('function',函式名),
                  '長欄名'=>array('wrap'),
                  );

searchSelect/searchSelect2 派值範例 兩者作用一樣,都是產生「一個部分文字輸入框 + 連動選單」,差別在:

  1. searchSelect:一上一下兩個欄,範例為 http://jendo.org/jendo/6year/sharingBooksToBorrowOld.php
  2. searchSelect2:一左一右,組成一組「欄位盤」,範例為 http://jendo.org/jendo/6year/sharingBooksToBorrow.php

select2/select22 派值範例 兩欄為連動關係,須同時存在

例如,依 ABC 欄的選擇結果,連動變換 DEF 欄的選單,則 ABC 欄與 DEF 欄的派值範例如下:
'ABC'=>array('select2',array(''=>'===請選擇===','1'=>'食','2'=>'衣','3'=>'行'),'DEF',$二維,1),
'DEF'=>array('select22',array(0=>'===請選擇==='))

進一步說明 ABC 欄的派值指示陣列

第0元素第1元素第2元素第3元素第4元素
select2array(''=>'===請選擇===','1'=>'食','2'=>'衣','3'=>'行')DEF$二維1(或0)
欄型第一選單陣列第二選單長欄名第二選單二維陣列第二選單以提示代表欄值

指示前須先定義 $二維(第二選單二維陣列)如下:

$二維=array();
$二維['1']['']='===請選擇===';
$二維['1']['1']='內食';
$二維['1']['2']='外食';
$二維['2']['']='===請選擇===';
$二維['2']['1']='衣帽';
$二維['2']['2']='美容保養';
$二維['2']['3']='其他';
$二維['3']['']='===請選擇===';
$二維['3']['1']='車資';
$二維['3']['2']='油錢';
$二維['3']['3']='停車費';
$二維['3']['4']='其他';

而被連動欄位的選單指示則較為固定:

長欄名'=>array('select22',array(0=>'===請選擇==='))

在此例中為:

'DEF'=>array('select22',array(0=>'===請選擇==='))

連動選單欄的 javascript 二維陣列變數名

資料表須有代名才會動

請參考 main()中函式分布地圖

  1. 連動選單是靠 javascript 二維陣列來連結兩個選單,此陣列是以第二選單的「表名_欄名」為 javascript 變數名。
  2. 但 MySQL 表名可以數字為首,但 javascript 變數名禁止以數字為首,所以此 javascript 二維陣列變數名應以「A表名_欄名」,以規避 javascript 變數名禁止以數字為首的語法規則。
  3. 第一處相關修改,在 main() 中輸出蒐尋排序表單段落裡,formType為select2時,「onChange='createOpt(\"".$toSelect."\",A".$f['as_name']."_".$f['field'].",this.selectedIndex);'」「A".$f['as_name']."_".$f['field']」即為 javascript 二維陣列變數名。
  4. 第二處相關修改,在 main() 中生成 javascript 表單輸入驗證段落裡,「$f='A'.$fa['as_name'].'_'.$fa['field'];」,$f即為 javascript 二維陣列變數名。
  5. 第三處相關修改,請見 mk_a($row) 函式定義,「$tmp[1]='A'.$fa['as_name']."_".$fa['field'];」$tmp[1]即為 javascript 二維陣列變數名。mk_a($row)的傳回值,最後被納入「編」連結的「onclick="postData(…);return false;"」postData()的最後一個引數。
  6. 第四處相關修改,請見 addElements($i,$value) 函式定義,製造表單中各可「插、編」欄,formType為select2時,「onChange='createOpt(\"f[".$f['as_name']."][".$f['field']."]\",A".$f['as_name']."_".$f['field'].",this.selectedIndex);'」,「A".$f['as_name']."_".$f['field']」即為 javascript 二維陣列變數名。

函式欄

表示法如派值範例。

函式寫在工作程式中,唯一引數為一陣列,可以有三個元素:

  1. 索引'colOrder'=>第幾欄
  2. 索引'value'=>欄值
  3. 索引'row'=>$row陣列

這三個元素對應到 colValue(第幾欄,$value,$row)

若未設定翻譯,秀原欄值;若設定翻譯,秀函式返回值。

例如:function f($value){return mb_substr($value['value'],0,1,'utf-8')."○○";}

會傳回欄值第一個字,後面則接著"○○",如:丁○○

searchSelect 欄

可由輸入的字,從指定的欄位中挑選符合的值形成表單

工作程式的寫法

<?php
include_once '../../constant.php';
include_once '../theme.php';
include_once CLASS_FILE_PATH."/database/etable.php";
if(isset($_POST['catchText'])){ // 如果有後送捕捉 keyin 值,還它一個相應選單
	$str="<select name=f[b][☉id]>\n";// 回應值
	$catchText=trim($_POST['catchText']);
	if($catchText!='' ){ // 如果有捕捉到字串
		$sql="SELECT * FROM 表1 a left join 表2 b on a.bid=b.bid WHERE 欄 like '%".$catchText."%' && (條件)";
		DB::connect(DSN);
		$result=DB::queryF($sql);
		if(DB::numRows($result)){
			while($row=mysql_fetch_array($result)){
				$str .= "<option value='".$row[0]."'>提示字:".$row['欄'].($row['分別欄']?',分別碼:'.$row['分別欄']:'')."</option>\n";
			}
		}else{$str.="<option value=''>===找不時的回應===</option>";}
	}else{
		$str.="<option value=''>===待輸入時的提示===</option>";// 此行同時提供編輯、插入、蒐尋關鍵字輸入空字串之回應
	}
	$str.='</select>';
	echo $str;
}else{ // 不是捕捉 keyin 值,正常 etable 
	$nowMsg="不符認證之提示";
	if(!isset($_REQUEST['exec_type'])){echo $html1;}
	$ET=new etable;
	$ET->loginTable=array('tableName'=>'表','name'=>'欄','psd'=>'欄','grp'=>'欄','canWorkGrp'=>'字串');
	$ET->editable='1';
	$ET->formType=array(
		'b.☉id'=>array('searchSelect', array(''=>'===待輸入時的提示===')),
		…
	);
	$ET->editables['ins']=array('b');
	$ET->sql[0]="select … from 表1 a,表2 b where a.☉id=b.☉id && 條件";
	$ET->main();
	if(isset($ET->checkin) && $ET->checkin==0){echo $nowMsg;}
	if(!isset($_REQUEST['exec_type'])){echo $html2;}
}
?>

配合的表單元件

  • formcatchtext.php:產生文字輸入區,沒name沒id,但可決定回應要從那一個id當中冒出來。
  • formselect-et.php:產生span包select或單純的select
    1. XoopsFormSelect方法增加最後一個引數:$asSpan,預設為0
    2. render方法依$asSpan的值決定select外面要不要加span,以及id要派給外層span還是內層的select
    3. 如果沒有設 id ,以name為id。

表單

諸方法

  • overPageXoopsForm,將$overPage陣列轉成XoopsForm的隱藏元素
  • form_same,插、編表單共同部分:$overPage、後送按鈕
  • form_edit,編表單
    1. 剔除演算式且沒有代名者,演算式出Label
    2. hidden處理
    3. unix_time的hidden處理
    4. 其他各欄,使用addElements方法處理
    5. form_same
  • addElements,先分 formType 有交代及 formType 沒交代
    • formType 有交代者:
      1. 排除hidden
      2. unix_time的非hidden處理
      3. date
      4. select
      5. searchSelect
      6. select2
      7. radio
      8. checkbox
      9. radioyn
      10. auto,出文字區塊
      11. 其他如 function ,出文字欄
    • formType 沒交代者:
      1. blob且binary,出Label
      2. blob非binary,出文字區塊
      3. 其他出文字欄

修改小日曆

xoopsform架構

  • form.php:定義 XoopsForm 類別
    1. 定義 addElement 方法
  • themeform.php:定義 XoopsThemeForm 繼承 XoopsForm,而 etable 中以 new XoopsThemeForm 得到表單物件。
    1. render():負責產生實體的 HTML code 。
  • etable 中以 表單物件->addElement(new 某元素類別) 來添加表單中的元素
  • formelementtray.php 製造一個 elements 的群組:定義 XoopsFormElementTray 繼承 XoopsFormElement
    1. 定義 addElement 方法,是將一個 element 加到 elements 陣列中
    2. 定義 render() 方法,是將含諸元素的陣列實體化為字串。