Nucleus

NP_match

2007年3月14日

Nucleus 3.3 の<%if%>の新しい機能、doIf() を使ったプラグインの大まかな構想がほぼ決定。NP_ExtendedIf の後継となるもので、より高いパフォーマンスと機能が期待できる。この構想に従い、NP_ExtendedIf は引退させることになりそう(3.24より前のNucleus用に、wiki のページは置いておくけれども)。ちょっと勇み足かもしれないけれど、ここに公開。

このプラグインは、なるべく肥大化しない方向で、シンプルなソースコードになるように開発したい。おそらく、100行以下を一つの目安とすると思う。

(最新版の情報は、Wiki にあります。)

使用方法

単一のアイテムを選択しているときのみ実行する場合
<%if(match,itemid=256)%>
(ここに表示したい内容を挿入)
<%endif%>
(アイテムidが256の時)

複数のアイテムを指定したい場合
<%if(match,itemid=^(64|128|256)$,ereg)%>
(ここに表示したい内容を挿入)
<%endif%>
(アイテムid, 64, 128, 256の3つを指定する場合)

<%if(match,itemid>=100,int)%>
<%if(match,itemid<=199,int)%>
(ここに表示したい内容を挿入)
<%endif%><%endif%>
(アイテムid, 100から199までを指定する場合)

<%if(match,itemid=/^1[0-9]{2}$/,preg)%>
(ここに表示したい内容を挿入)
<%endif%>
(アイテムid, 100から199までを指定する別の方法)

カテゴリー、サブカテゴリー指定の場合は、上記の『itemid』をそれぞれ『catid』もしくは『subcatid』と変更。

ブログのトップページなど、一部のページを表示しているときのみ実行する場合

<%if(match,REQUEST_URI=/blog/)%>
(ここに表示したい内容を挿入)
<%endif%>
(URLが『http://www.sample.com/blog/』の時)

URLに『?extendedif=xxx』が指定されているとき

<%if(match,extendedif=xxx)%>
(ここに表示したい内容を挿入)
<%endif%>



注意:<%match(default,preg)%>などでメソッド指定した場合、以後の<%if(match)%>命令のすべてに適応される。2回目以降の<%if(match)%>命令で、元通り文字列として判定したい場合は、<%match(default,str)%>を実行する必要がある。


ソースコード
(4月18日改定。とりあえず、βバージョンとします。ver 0.1.x と ver 0.2.x では文法が異なります。)
<?php 
class NP_match extends NucleusPlugin { 
    function getName() { return 'NP_match'; }
    function getMinNucleusVersion() { return 330; }
    function getAuthor()  { return 'Katsumi'; }
    function getVersion() { return '0.2.3'; }
    function getURL() {return 'http://www.recfor.net/nucleus/index.php?itemid=265';}
    function getDescription() { return $this->getName().' plugin.  Usage: &lt;%if(match,name=str)%&gt; etc.'; } 
    function supportsFeature($what) { return ($what=='SqlTablePrefix')?1:0; }
    var $conf=array('method'=>'str', 'decode'=>'', 'data'=>'');
    var $securemode=false;
    function doSkinVar($skintype,$p1='',$p2=''){
        switch($p1){
        case 'default': $this->conf=$this->setting($p2); break;
        default: break;
        }
    }
    function doIf($p1,$p2=''){
        global $HTTP_GET_VARS,$HTTP_SERVER_VARS;
        if (!is_array($_GET)) $_GET=&$HTTP_GET_VARS;
        if (!is_array($_SERVER)) $_SERVER=&$HTTP_SERVER_VARS;
        // Initialize
        if (!preg_match('/^([^<>=]+)([<>=]+)([\S\s]+)$/',$p1,$matches)) return $this->_error('Syntax error:'.$p1);
        list($p1,$name,$comp,$value)=$matches;
        if (!is_array(  $matchconf=$this->setting($p2)  )) return false;
        // Origin of data (Get $var from data)
        switch($matchconf['data']){
        case 'get':
            if (isset($_GET[$name]))    $var=$_GET[$name];
            break;
        case 'globals':
            if (isset($GLOBALS[$name])) $var=$GLOBALS[$name];
            break;
        case 'server':
            if (isset($_SERVER[$name])) $var=$_SERVER[$name];
            break;
        default:
            if     (isset($_GET[$name]))    $var=$_GET[$name];
            elseif (isset($GLOBALS[$name])) $var=$GLOBALS[$name];
            elseif (isset($_SERVER[$name])) $var=$_SERVER[$name];
        }
        if (!isset($var)) return false;
        // Decode the regular expression or not (convert $value that is encoded regular expression)
        switch($matchconf['decode']){
            case 'rawurldecode': case 'urldecode':
                $value=call_user_func($matchconf['decode'],$value);
            default: break;
        }
        // Try matching
        switch($matchconf['method']){
        case 'preg': case 'preg_match': case 'ereg': case 'eregi':
            return $this->_regexp($matchconf['method'],$value,$var);
        case 'int': case 'integer':
            $var=(int)$var;
            $var2=(int)$value;
            break;
        case 'float': case 'double': case 'real':
            $var=(float)$var;
            $var2=(float)$value;
            break;
        case 'str': case 'string':
        default:
            $var=(string)$var;
            $var2=(string)$value;
            break;
        }
        switch($comp){
            case '=' : case '==': return ($var == $var2);
            case '!=': case '<>': return ($var != $var2);
            case '<=': case '=<': return ($var <= $var2);
            case '>=': case '=>': return ($var >= $var2);
            case '<' :            return ($var <  $var2);
            case '>' :            return ($var >  $var2);
            default: return $this->_error('Syntax error:'.$p1.' near "'.$comp.'"');
        }
    }
    function _regexp($method,$value,$var){
        if ($method=='preg') $method='preg_match';
        if (($ret=@call_user_func($method,$value,$var))===false) return $this->_error('Regular expression error: "'.$value.'"');
        return (bool)$ret;
    }
    function setting($value){
        if (!$value) return $this->conf;
        $matchconf=$this->conf;
        foreach(explode('|',$value) as $each) if ($each) {
            switch (count(  $each=explode('=',$each)  )) {
                case 1: $matchconf['method']=$each[0]; break;
                case 2: $matchconf[$each[0]]=$each[1]; break;
                default: return $this->_error('Syntax error:'.$p1.' near "'.$each[0].'"');
            }
        }
        return $matchconf;
    }
    function _error($msg){
        echo '<!-- --><b>'.$this->getName().' - '.htmlspecialchars($msg).'</b>';
        if ($this->securemode) exit;
        return false;
    }
}
?>

コメント

コメントはありません

コメント送信