<?php
/**
 *  Sync/Read.php
 *
 *  @author     {$author}
 *  @package    Secioss
 *  @version    $Id: skel.action.php,v 1.10 2006/11/06 14:31:24 cocoitiban Exp $
 */

/**
 *  sync_readフォームの実装
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Secioss
 */
class Secioss_Form_SyncRead extends Secioss_ActionForm
{
    /** @var    bool    バリデータにプラグインを使うフラグ */
    var $use_validator_plugin = true;

    /**
     *  @access private
     *  @var    array   フォーム値定義
     */
    var $form = array(
        'sync_system_list' => array(
            'type'          => array(VAR_TYPE_STRING),
            'form_type'     => FORM_TYPE_CHECKBOX,
            'name'          => 'システム選択',
            'required'      => true
        ),
        'user_id' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => 'ユーザID'
        ),
        'user_name' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '氏名'
        ),
        'group_name' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => 'グループ名'
        ),
        'tenant' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_SELECT,
            'name'          => 'テナント',
            'option'        => 'tenant_select'
        ),
        'entry' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_RADIO,
        ),
        'file_output' => array(
            'type'          => VAR_TYPE_INT,
            'form_type'     => FORM_TYPE_HIDDEN,
            'default'       => 0
        ),
        'operation' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_HIDDEN,
            'required'       => true
        ),
        'search' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_HIDDEN,
        )
    );
}

/**
 *  sync_readアクションの実装
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Secioss
 */
class Secioss_Action_SyncRead extends Secioss_ActionClass
{
    /**
     *  sync_readアクションの前処理
     *
     *  @access public
     *  @return string      遷移名(正常終了ならnull, 処理終了ならfalse)
     */
    function prepare()
    {
        if ($this->af->get("search") == true){
            return 'sync_search';
        }

        if ($this->af->get('operation') != "search") {
            $this->af->setApp('total_num', 0);
            return 'sync_read';
        }

        if ($this->af->validate() > 0) {
            $this->af->setApp('total_num', 0);
            $this->ae->add(null, $this->getInvalidValMsg($this->getErrorFormName()));

            return 'sync_read';
        }

        return null;
    }

    /**
     *  sync_readアクションの実装
     *
     *  @access public
     *  @return string  遷移名
     */
    function perform()
    {
        $auth =& $this->backend->getManager('Auth');
        $confmgr =& $this->backend->getManager('Config');
        $logger =& $this->backend->getLogger();
        $conf = $this->config->get('secioss');
        $login_user = $this->session->get('user');

        if(!$sync_list = $this->af->get('sync_system_list')) $sync_list = array();
        $user_id = $this->af->get('user_id');
        $user_name = $this->af->get('user_name');
        $group_name = $this->af->get('group_name');
        $tenant = $this->af->get('tenant');
        $entry = $this->af->get('entry');
        $file_output = $this->af->get('file_output');
        $filter = '';
        $base = null;
        $total_num = 0;
        $list = array();

        $role = $this->session->get('role');

        if ($role == 'tenant_admin') {
            $tenant = $this->session->get('tenant');
        }

        if ($tenant) {
            $base = $conf['area']['id']."=$tenant";
            if (isset($conf['system'])) {
                $base = "$base,ou=Master";
            }
        }

        $user_id = preg_replace(array("/\(/","/\)/"), array('\\\5C\\\28','\\\5C\\\29'), $user_id);
        $user_name = preg_replace(array("/\(/","/\)/"), array('\\\5C\\\28','\\\5C\\\29'), $user_name);
        $group_name = preg_replace(array("/\(/","/\)/"), array('\\\5C\\\28','\\\5C\\\29'), $group_name);
        if($entry == 'group'){
            foreach ($conf['group']['objectclass'] as $oc) {
                $filter = $filter ? '(&'.$filter."(objectClass=$oc))" : "(objectClass=$oc)";
            }
            if($group_name) {
                if(!preg_match('/\*/', $group_name)) {
                    $group_name = "*$group_name*";
                }
                $filter = '(&'.$filter.'('.$conf['group']['id'].'='.$group_name.'))';
            }
        }else if($entry == 'user'){
            foreach ($conf['group']['objectclass'] as $oc) {
                $filter = $filter ? '(&'.$filter."(objectClass=$oc))" : "(objectClass=$oc)";
            }
            if ($user_id) {
                if(!preg_match('/\*/', $user_id)) {
                    $user_id = "*$user_id*";
                }
                $filter = '(&'.$filter.'('.$conf['user']['id'].'='.$user_id.'))';
            }
            if ($user_name) {
                if(!preg_match('/\*/', $user_name)) {
                    $user_name = "*$user_name*";
                }
                $filter = '(&'.$filter.'(cn='.$user_name.'))';
            }
        }

        if(!$attrs = $auth->readSync($sync_list, $filter, $base)){
            $logger->log(LOG_ERR, "$login_user faild to read lismsync");
            $this->ae->add(null, S_INTERNAL_ERR_MSG);
            return 'sync_read';
        }

        if ($file_output) {
            $fp = new File();
            $file = BASEDIR.'/tmp/sync'.date('YmdHis').'.csv';
        }

        foreach($sync_list as $sync){
            if(!isset($attrs['lismSyncErrMessage'])) break;

            foreach($attrs['lismSyncErrMessage'] as $msg){
                if (preg_match('/^[^=]+=([^,]+),'.$conf['category']['id'].'=([^,]+),'.$conf['group']['objectdn'].",ou=$sync.*\"(.*)\"/i", $msg, $matches)) {
                    $type = "グループ：$matches[2]";
                    $message = $matches[3];
                } else if (preg_match('/^[^=]+=([^,]+),'.$conf['user']['objectdn'].",ou=$sync.*\"(.*)\"/i", $msg, $matches)) {
                    $type = "ユーザ";
                    $message = $matches[2];
                } else {
                    continue;
                }

                if ($file_output) {
                    $data = array($sync,
                                  $matches[1],
                                  $type,
                                  $message
                                 );

                    mb_convert_variables('SJIS', 'UTF-8', $data);         

                    $rc = $fp->writeLine($file, implode(',', $data));
                    if (PEAR::isError($rc)) {
                        $logger->log(LOG_ERR, "$login_user failed to write CSV file: ".$rc->getMessage());
                        unlink($file);
                        return null;
                    }
                } else {
                    array_push($list, array("sync"      => $sync,
                                            "name"      => $matches[1],
                                            "type"      => $type,
                                            "message"   => $message
                                           ));
                }
                $total_num++;
            }
        }

        if ($file_output) {
            $fp->close($file, FILE_MODE_APPEND);

            if (!$auth->downloadFile($file)) {
                $logger->log(LOG_ERR, "$login_user failed to download CSV file")
;
                unlink($file);
                return null;
            }
            unlink($file);

            return null;
        }

        $this->af->setApp('list',$list);
        $this->af->setApp('total_num',$total_num);
        //空白があると値がおかしくなるためエスケープする
        $filter = preg_replace("/ /",'\\\20',$filter);
        $this->af->setApp('systems', join(',', $sync_list));
        $this->af->setApp('filter', $filter);

        return 'sync_read';
    }
}
?>
