ソフト作成ログ -3ページ目

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 ? '' : '&amp;' ) . '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が空の状況かは、なぞ(´・ω・`)?? 空の場合もあるが、スマイルが登録されていないときなどは、もう一度問い合わせる必要はないのでは。 )


スマイルごとの写真をのっけて、も