xoops token
Xoops TOKEN
TOKENとは、そのトークンの持ち主が誰であるのかや、どのような権利を持っているのかが記載されたものです。
xoopsのtokenは、スパム行為を防ぐために使われています。(多分(・_・;))
ソースを紹介する前にざっと行っていることを説明します。
前座
フォームで投稿する場合form をpostかgetで飛ばしますよね。
その際に、input type="hidden" に value="token"をつけて送ります。
tokenとほぼ同じものを $_SEESION に入れときます。
それが同じであるかどうかで、指定されたフォームから飛んできたかどうか確認しています。
ソース bluebb の btickets.phpから
<?php
// Sting_Band's Ticket Class
// based on GIJOE's Ticket Class (based on Marijuana's Oreteki XOOPS)
// nobunobu's suggestions are applied
if( ! class_exists( 'XoopsBluesTicket' ) ) {
class XoopsBluesTicket {
var $_errors = array() ;
var $_latest_token = '' ;
// render form as plain html
function getTicketHtml( $salt = '' , $timeout = 1800 )
{
return '<input type="hidden" name="XOOPS_BLUES_TICKET" value="'.$this->issue( $salt , $timeout ).'" />' ;
}
// returns an object of XoopsFormHidden including theh ticket
function getTicketXoopsForm( $salt = '' , $timeout = 1800 )
{
return new XoopsFormHidden( 'XOOPS_BLUES_TICKET' , $this->issue( $salt , $timeout ) ) ;
}
// returns an array for xoops_confirm() ;
function getTicketArray( $salt = '' , $timeout = 1800 )
{
return array( 'XOOPS_BLUES_TICKET' => $this->issue( $salt , $timeout ) ) ;
}
// return GET parameter string.
function getTicketParamString( $salt = '' , $noamp = false , $timeout=1800 )
{
return ( $noamp ? '' : '&' ) . 'XOOPS_BLUES_TICKET=' . $this->issue( $salt, $timeout ) ;
}
// issue a ticket
function issue( $salt = '' , $timeout = 1800 )
{
// create a token
list( $usec , $sec ) = explode( " " , microtime() ) ;
$token = crypt( $salt . $usec . $_SERVER['PATH'] . $sec ) ;
$this->_latest_token = $token ;
if( empty( $_SESSION['XOOPS_BLUES_STUBS'] ) ) $_SESSION['XOOPS_BLUES_STUBS'] = array() ;
// limit max stubs 10
if( sizeof( $_SESSION['XOOPS_BLUES_STUBS'] ) > 10 ) {
$_SESSION['XOOPS_BLUES_STUBS'] = array_slice( $_SESSION['XOOPS_BLUES_STUBS'] , -10 ) ;
}
// store stub
$_SESSION['XOOPS_BLUES_STUBS'][] = array(
'expire' => time() + $timeout ,
'ip' => $_SERVER['REMOTE_ADDR'] ,
'token' => $token
) ;
// paid md5ed token as a ticket
return md5( $token . XOOPS_DB_PREFIX ) ;
}
// check a ticket
function check( $post = true )
{
$this->_errors = array() ;
// CHECK: stubs are not stored in session
if( empty( $_SESSION['XOOPS_BLUES_STUBS'] ) || ! is_array($_SESSION['XOOPS_BLUES_STUBS'])) {
$this->clear() ;
$this->_errors[] = 'Invalid Session' ;
return false ;
}
// get key&val of the ticket from a user's query
if( $post ) {
$ticket = empty( $_POST['XOOPS_BLUES_TICKET'] ) ? '' : $_POST['XOOPS_BLUES_TICKET'] ;
} else {
$ticket = empty( $_GET['XOOPS_BLUES_TICKET'] ) ? '' : $_GET['XOOPS_BLUES_TICKET'] ;
}
// CHECK: no tickets found
if( empty( $ticket ) ) {
$this->clear() ;
$this->_errors[] = 'Irregular post found' ;
return false ;
}
// gargage collection & find a right stub
$stubs_tmp = $_SESSION['XOOPS_BLUES_STUBS'] ;
$_SESSION['XOOPS_BLUES_STUBS'] = array() ;
foreach( $stubs_tmp as $stub ) {
// default lifetime 30min
if( $stub['expire'] >= time() ) {
if( md5( $stub['token'] . XOOPS_DB_PREFIX ) === $ticket ) {
$found_stub = $stub ;
} else {
// store the other valid stubs into session
$_SESSION['XOOPS_BLUES_STUBS'][] = $stub ;
}
} else {
if( md5( $stub['token'] . XOOPS_DB_PREFIX ) === $ticket ) {
// not CSRF but Time-Out
$timeout_flag = true ;
}
}
}
// CHECK: no right stub found
if( empty( $found_stub ) ) {
$this->clear() ;
if( empty( $timeout_flag ) ) $this->_errors[] = 'Invalid Session' ;
else $this->_errors[] = 'Time out' ;
return false ;
}
// CHECK: different ip
/* if( $found_stub['ip'] != $_SERVER['REMOTE_ADDR'] ) {
$this->clear() ;
$this->_errors[] = 'IP has been changed' ;
return false ;
} */
// all green
return true;
}
}
なぞぃ関数
sizeof = count (配列の数を返す)
microtime (マイクロ秒まで返す関数) 一応マイクロ秒は 1/1000秒(((( ;°Д°))))ストップウォッチじゃ無理だ!!
ex) $stamp = microtime();
echo $stamp; // 0.54121254マイクロ秒 1086400546 秒
list($msec,$sec)=explode(" ",$stamp);
echo(float)$sec + (float)$msec; // 1086400546.63
流れ
クラスなので、メソッドごとの流れを話します。
function getTicketHtml( $salt = '' , $timeout = 1800 )
{
return '<input type="hidden" name="XOOPS_BLUES_TICKET" value="'.$this->issue( $salt , $timeout ).'" />' ;
}
ここで、チケットをフォームに隠して送ります。
$this->issue( $salt , $timeout )でvalueを作ってます。
// create a token
list( $usec , $sec ) = explode( " " , microtime() ) ;
$token = crypt( $salt . $usec . $_SERVER['PATH'] . $sec ) ;
$this->_latest_token = $token ;
このように、マイクロタイムを使ってトークンやチケットを作ります。
そして、この時間は有効時間を調べるさいにも使われています。
// store stub
$_SESSION['XOOPS_BLUES_STUBS'][] = array(
'expire' => time() + $timeout ,
'ip' => $_SERVER['REMOTE_ADDR'] ,
'token' => $token
) ;
// paid md5ed token as a ticket
return md5( $token . XOOPS_DB_PREFIX ) ;
}
$_SESSIONに入れるトークン とチケットとしてのトークンにそれぞれデーターを格納します。
if( md5( $stub['token'] . XOOPS_DB_PREFIX ) === $ticket )
最後に$_SESSIONのトークンとPOSTかGETで手にしたトークンを比べてます。
他にも色々やってます。有効期限とかです。
xoops form XoopsFormSelectMatchOption
xoops form XoopsFormSelectMatchOption
class XoopsFormSelectMatchOption extends XoopsFormSelect
XoopsFormSelectクラスのサブクラス。
機能はこれだけ、
function XoopsFormSelectMatchOption($caption, $name, $value=null, $size=1)
{
$this->XoopsFormSelect($caption, $name, $value, $size, false);
$this->addOption(XOOPS_MATCH_START, _STARTSWITH);
$this->addOption(XOOPS_MATCH_END, _ENDSWITH);
$this->addOption(XOOPS_MATCH_EQUAL, _MATCHES);
$this->addOption(XOOPS_MATCH_CONTAIN, _CONTAINS);
}
結果
<option value='0'>前方一致</option>
<option value='1'>後方一致</option>
<option value='2'>完全一致</option>
<option value='3'>次の単語を含む</option>
あいまい検索をする際につかうものです。(たぶん)
XOOPS Form XoopsFormSelect
XOOPS Form XoopsFormSelect
XoopsFormSelect は、セレクトボックスをつくるためのクラスです。
ソース
$group_select = new XoopsFormSelect($caption,$name,$value=null,$size=1,$muletiple=false);
$group_select->addOption(value,name);
$group_select->addOptionArray(array(value=>name));
$group_select->setValue('value');
使い方
XoopsFormSelect の引数
$caption タイトルを表示する。
$name select の name id の値になる。
$value nullのはず(ノω・、)
$size select のサイズ
$muletiple 複数選択できるようにする。
上のように引数に代入すると、色々なことができます。
addOption、addOptionarray
オプションを追加します。
setValue
checkedをつける。
具体的に結果
$group_select = new XoopsFormSelect'', "groupid",'','5',true);
$group_select->addOptionArray(array(0=>_MM_ALLGROUP));
$group_select->addOptionArray($member_handler->getGroupList($criteria));
$group_select->setValue('1');
<select size='1' name='groupid[]' id='groupid[]' multiple='multiple'>
<option value='0' selected='selected'>_MM_ALLGROUP</option>
<option value='1'>test</option>
<option value='2'>登録ユーザ</option>
<option value='3'>ゲスト</option>
<option value='4'>サイト管理者</option>
</select>
xoops $member_handler ユーザー数を獲得する。
xoops $member_handler getUserCount
ユーザー数を獲得する方法です。
ソース
$member_handler =& xoops_gethandler('member');
$total = $member_handler->getUserCount(new Criteria('$column', $value, $operator))
流れ;
ユーザー数をゲットするものですが、 おなじみのxoops_gethandlerでmemberのカーネルクラス memberhandlerクラスのインスタンスを生成し、そのオブジェクト $member_handler に格納。
そして、getUserCountというメソッドを実行!!
引数はCriteriaクラスのオブジェクトです。
$column コラム名
$value 値
$operator デフォルト =
具体的な使い方
Criteriaクラスによって、条件を設定します。
例えば、投稿数が、20以上の人の数を調べる場合
$column posts
$value 20
$operator >=
補足ソース
function getUserCount($criteria = null)
{
return $this->_uHandler->getCount($criteria);
}
function getCount($criteria = null)
{
$sql = 'SELECT COUNT(*) FROM '.$this->db->prefix('users');
if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
$sql .= ' '.$criteria->renderWhere();
}
$result = $this->db->query($sql);
if (!$result) {
return 0;
}
list($count) = $this->db->fetchRow($result);
return $count;
}
Smilies xoops
Smilies xoops
スマイルの表示の仕方を説明します。
class/module.textsanitizer.php
function &smiley($message)
{
$db =& Database::getInstance();
if (count($this->smileys) == 0) {
if ($getsmiles = $db->query("SELECT * FROM ".$db->prefix("smiles"))){
while ($smiles = $db->fetchArray($getsmiles)) {
$message = str_replace($smiles['code'], '<img src="'.XOOPS_UPLOAD_URL.'/'.htmlspecialchars($smiles['smile_url']).'" alt="" />', $message);
array_push($this->smileys, $smiles);
}
}
}
elseif (is_array($this->smileys)) {
foreach ($this->smileys as $smile) {
$message = str_replace($smile['code'], '<img src="'.XOOPS_UPLOAD_URL.'/'.htmlspecialchars($smile['smile_url']).'" alt="" />', $message);
}
}
return $message;
}
xoopscodes.php
function xoopsSmilies($textarea_id)
{
$myts =& MyTextSanitizer::getInstance();
$smiles = $myts->getSmileys();
if (empty($smileys)) {
$db =& Database::getInstance();
if ($result = $db->query('SELECT * FROM '.$db->prefix('smiles').' WHERE display=1')) {
while ($smiles = $db->fetchArray($result)) {
//hack smilies move for the smilies !!
echo "<img src='".XOOPS_UPLOAD_URL."/".htmlspecialchars($smiles['smile_url'])."' border='0' onmouseover='style.cursor=\"hand\"' alt='' onclick='xoopsCodeSmilie(\"".$textarea_id."\", \" ".$smiles['code']." \");' />";
//fin du hack
}
}
} else {
$count = count($smiles);
for ($i = 0; $i < $count; $i++) {
if ($smiles[$i]['display'] == 1) {
//hack bis
echo "<img src='".XOOPS_UPLOAD_URL."/".$myts->oopsHtmlSpecialChars($smiles['smile_url'])."' border='0' alt='' onclick='xoopsCodeSmilie(\"".$textarea_id."\", \" ".$smiles[$i]['code']." \");' onmouseover='style.cursor=\"hand\"' />";
//fin du hack
}
}
}
説明
$myts =& MyTextSanitizer::getInstance();
$smiles = $myts->getSmileys();
で登録されているスマイルをデーターベースからゲットする。
できない場合はif (empty($smileys)) {
の中身を実行。(どういうとき、$smileysが空の状況かは、なぞ(´・ω・`)?? 空の場合もあるが、スマイルが登録されていないときなどは、もう一度問い合わせる必要はないのでは。 )
スマイルごとの写真をのっけて、も