<?php
/**
 * マネージャ プラグインのイベント処理など
 */
class Platy_Manager
{
    private $CExts;
    private $CVars;
    public  $delim;
    public  $module;
    
    // クラスのインスタンスを保持する
    private static $instance;

    // private なコンストラクタ。オブジェクトが直接生成されるのを防ぐ
    private function __construct() {
        $this->delim = '(\[%|%\])';
        $this->module = '';
    }

    // singleton メソッド
    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }
        return self::$instance;
    }
    
    // ユーザーがインターフェースを複製するのを防ぐ
    public function __clone()
    {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }
    
    /**
     * イベントを発生させる
     * @param string $eventName イベント名
     */
    public function raiseEvent($eventName, $data = 0) {
        global $config;
        //echo "notify({$eventName})<br />\n";
        $this->loadCExts();
        for ($i = 0; $i < count($this->CExts); $i++) {
            $CExt_name = $this->CExts[$i]['name'];
            $CExt_class_name = 'Platy_CExt_' . $CExt_name;
            //echo $CExt_class_name;
            require_once(APP_PATH . 'models/CExt/' . $CExt_name . '.php');
            $CExt = new $CExt_class_name();
            $method_name = 'event_' . $eventName;
            if (method_exists($CExt, $method_name) == true) {
                $CExt->$method_name();
            }
        }
    }
    
    /**
     * CExtのロード
     */
    private function loadCExts() {
        global $db;
        if (!isset($this->CExts)) {
            $sql = "SELECT name FROM Platy_CExt ORDER BY ordering";
            $rows = $db->fetchAll($sql);
            for ($i = 0; $i < count($rows); $i++) {
                $row = $rows[$i];
                $this->CExts[] = array('name'=>$row['name']);
            }
        }
        return true;
    }
    
    /**
     * CVarのロード
     */
    private function loadCVars() {
        global $db;
        if (!isset($this->CVars)) {
            $sql = "SELECT name FROM Platy_CVar ORDER BY ordering";
            $rows = $db->fetchAll($sql);
            for ($i = 0; $i < count($rows); $i++) {
                $row = $rows[$i];
                $this->CVars[] = array('name'=>$row['name']);
            }
        }
        return true;
    }
    
    /**
     * CVar()を展開する
     */
    public function parseCVar($s) {
        global $db, $config;
        $this->loadCVars();
        $retval = '';
        $pieces = preg_split('/' . $this->delim . '/', $s);
        //var_dump($pieces);
        $maxidx = sizeof($pieces);
        for ($idx = 0; $idx < $maxidx; $idx++) {
            $retval = $retval . $pieces[$idx];
            $idx++;
            if ($idx < $maxidx) {
                $var_code = $this->extractCVar($pieces[$idx]);
                $retval = $retval . $var_code;
            }
        }
        return $retval;
    }
    
    /**
     * 変数を展開する
     * var_name(parm1, parm2, ...)
     */
    private function extractCVar($arg) {
        global $config;
        //echo 'callCExt:$action1=' . $action . "<br />\n";
        $action = $arg;
        if (strstr($action, '(')) {
            $paramStartPos = strpos($action, '(');
            $params = substr($action, $paramStartPos + 1, strlen($action) - $paramStartPos - 2);
            $action = substr($action, 0, $paramStartPos);
            $params = explode (',', $params);
            $params = array_map('trim',$params);
        } else {
            // no parameters
            $params = array();
        }
        $name = $action;
        //echo "name=" . $name . ",params=" . var_dump($params) . "<br />\n";
        
        $CVar_name = $name;
        $CVar_class_name = 'Platy_CVar_' . $name;
        //var_dump($this->CVars);
        
        ob_start();
        
        $found = FALSE;
        for ($i = 0; $i < count($this->CVars); $i++) {
            if ($CVar_name == $this->CVars[$i]['name']) {
                $found = TRUE;
                break;
            }
            else {
            }
        }
        if ($found == false) {
            echo "[CVar {$CVar_name} doesn't exist]<br />\n";
        }
        else {
            require_once(APP_PATH . 'models/CVar/' . $CVar_name . '.php');
            $CVar = new $CVar_class_name();
            if (method_exists($CVar, 'doCVar') == FALSE) {
                echo "[CVar method doesn't exist]<br />\n";
            }
            else {
                $CVar->doCVar($params);
            }
        }
        $doVar_code = ob_get_contents();
        ob_end_clean();
        return $doVar_code;
    }
}
?>