<?php
/*
 * This file is part of INQMAN
 *
 * Copyright(c) 2008 BULLHEAD,INC. ALL RIGHTS RESERVED.
 *
 * http://www.bullhead.co.jp/
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation;
 * either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * 回答＆コメント管理のロジッククラス
 * 
 * 
 *
 */
class Inqman_ReplyModel extends Inqman_AbstractDao
{
        
    const PRIORITY_CODE_HIGH     = '10';
    const PRIORITY_CODE_XHIGH    = '20';
    const PRIORITY_CODE_MIDDLE   = '30';
    const PRIORITY_CODE_XLOW     = '40';
    const PRIORITY_CODE_LOW      = '50';
    
    const RES_METHOD_CODE_EMAIL  = '10';
    const RES_METHOD_CODE_TEL    = '20';
    const RES_METHOD_CODE_WEB    = '30';
    
    const RES_TYPE_CODE_REPLY    = '1';
    const RES_TYPE_CODE_COMMENT  = '2';
    
    protected $_name = 't_reply';
    
    /**
     * 回答情報を1件取得する
     * 
     * @param integer $reply_id
     * @return array 回答情報を連想配列で返す
     */
    public function getOneReply($reply_id)
    {
        $data = null;
        if(!empty($reply_id) && !is_array($reply_id)) {
            $db = $this->getAdapter();
            $select = $db->select()
                ->from(array('r' => 't_reply'))
                ->joinLeft(array('u' => 'm_user'), 'r.respondent_id=u.id', array('respondent_user_id' => 'user_id', 'respondent_name' => 'name'))
                ->where('r.id=?', $reply_id)
//                ->where('r.type=1');
            ;
            $this->_logger->info('Inqman_ReplyModel->getOneReply : ' . $select->__toString());
            $data = $db->fetchRow($select);
        }
        return $data;    
    }
    
    /**
     * 指定された問い合わせへの回答情報を取得する
     * 
     * @param integer $inquiry_id
     * @return array 回答情報を配列で返す
     */
    public function getRepliesByInquiryId($inquiry_id)
    {
        $replies = null;
        if(!empty($inquiry_id) && !is_array($inquiry_id)) {
            $db = $this->getAdapter();
            $select = $db->select()
                ->from(array('r' => 't_reply'))
                ->joinLeft(array('u' => 'm_user'), 'r.respondent_id=u.id', array('respondent_user_id' => 'user_id', 'respondent_name' => 'name'))
                ->where('r.inquiry_id=?', $inquiry_id)
                ->where('r.parent_id=?', 0) //親記事
                ->order('r.reply_datetime ASC')
            ;
            $replies = $db->fetchAssoc($select);
            $replies = $this->_getChildResponses($replies);
        }
        return $replies;  
    }
    
    /**
     * 指定された問い合わせへの回答件数を取得する
     * 
     * @param integer $inquiry_id
     * @return integer 回答件数を数値で返す
     */
    public function getResponsesDataSizeByInquiryId($inquiry_id)
    {
        if(!empty($inquiryId) && !is_array($inquiry_id)) {
            $db = $this->getAdapter();
            $select = $db->select()
                ->from(array('r' => 't_reply'), array('count(*)'))
                ->where('r.inquiry_id=?', $inquiry_id)
                ->where('r.type=?', 1)
            ;
            $count = $db->fetchOne($select);
            
            return $count;
        }
        return null;  
    }
    
    /**
     * 指定された問い合わせへのコメント件数を取得する
     * 
     * @param integer $inquiry_id
     * @return integer 回答件数を数値で返す
     */
    public function getCommentsDataSizeByInquiryId($inquiry_id)
    {
        if(!empty($inquiryId) && !is_array($inquiry_id)) {
            $db = $this->getAdapter();
            $select = $db->select()
                ->from(array('r' => 't_reply'), array('count(*)'))
                ->where('r.inquiry_id=?', $inquiry_id)
                ->where('r.type=?', 2)
            ;
            $count = $db->fetchOne($select);
            
            return $count;
        }
        return null;  
    }
    
    /**
     * 回答（コメント）を登録する
     * 
     */
    public function createReply($values)
    {
        $reply_id = null;
        try {
            $db = $this->getAdapter();
            $db->beginTransaction();
            
            $parent_id = empty($values['parent_id']) ? 0 : intval($values['parent_id']);
            $select = $db->select()->from('t_reply', 'level')->where('id=?', $parent_id);
            $level = $db->fetchOne($select);
            $values['level'] = intval($level) +1;
            
            if (empty($values['reply_datetime'])) {
                $values['reply_datetime'] = date("Y-m-d H:i:s", time());
            }
            $db->insert('t_reply', $values);
            
            $reply_id = $db->lastInsertId('t_reply');
            
            $db->commit();
        } catch (Exception $e) {
            $db->rollBack();
            throw $e;
        }
        return $reply_id;
    }
    
    /**
     * 回答重要度をKEY=CODE,VALUE=NAMEの配列で返す
     * 
     * @access public
     * @return array
     */
    public function getPriorityOptions()
    {
        $codes = self::getPriorityCodes();
        $translator = Zend_Registry::get('Zend_Translate');
        $options = array();
        foreach ($codes as $code) {
            $options[$code] = $translator->translate("reply.priority.label.{$code}");
        }
        return $options;
    }
    
    /**
     * 重要度コードを取得する
     * 
     * @access public
     * @return 重要度コードを配列で返す
     */
    public static function getPriorityCodes()
    {
        $priority_codes = array(
            self::PRIORITY_CODE_HIGH,
            self::PRIORITY_CODE_XHIGH,
            self::PRIORITY_CODE_MIDDLE,
            self::PRIORITY_CODE_XLOW,
            self::PRIORITY_CODE_LOW,
        );
        return $priority_codes;
    }
    
    /**
     * 回答方法をKEY=CODE,VALUE=NAMEの配列で返す
     * 
     * @access public
     * @return array
     */
    public function getMethodOptions()
    {
        $codes = self::getResMethodCodes();
        $translator = Zend_Registry::get('Zend_Translate');
        $options = array();
        foreach ($codes as $code) {
            $options[$code] = $translator->translate("reply.method.label.{$code}");
        }
        return $options;
    }
    
    /**
     * 回答方法コードを取得する
     * 
     * @access public
     * @return 回答方法コードを配列で返す
     */
    public static function getResMethodCodes()
    {
        $method_codes = array(
            self::RES_METHOD_CODE_EMAIL,
            self::RES_METHOD_CODE_TEL,
            //self::RES_METHOD_CODE_WEB,
        );
        return $method_codes;
    }
    
    /** Mail Sender **/
    
    /**
     * メール送信処理
     */
    public function sendMail($event_action_id, $criteria)
    {
        //メール送信
        $acl_model          = new Inqman_AclModel();
        $event_model        = new Inqman_EventModel();
        $mailtemplate_model = new Inqman_MailtemplateModel();
        $mail_sender        = new Inqman_MailSender();
        $service_model      = new Inqman_ServiceModel();
        $inquiry_model      = new Inqman_InquiryModel();
        
        //イベント設定取得
        $rows = $event_model->getEvanetActionTarget($criteria['service_id'], $event_action_id);
        
        //回答対象の問い合わせ情報取得
        $inquiry = $inquiry_model->getOneInquiry($criteria['inquiry_id']);
        $received_from = $inquiry['received_from'];
        $inquiry_number = $inquiry['number'];
        
        //サービス情報を取得
        $service_id = $inquiry['service_id'];
        $service = $service_model->getOneService($service_id);
        $service_code = $service['code'];
        
        foreach ($rows as $row) {
            //対象者取得
            $event_to = intval($row['event_to']);
            $send_to = array();
            if($event_to!=0) {
                if ($event_to == 1) $send_to[] = $received_from;
            } else {
                $users = (array) $acl_model->getUsersByAuthority($row['authority_id']);
                foreach ($users as $user) {
                    if (!empty($user['mailaddress'])) {
                        $send_to[] = $user['mailaddress'];
                    }
                }
            }
            $subject = "[{$service_code}:{$inquiry_number}]" . $row['subject'];
            
            //システム変数置換
            $subject = $mailtemplate_model->replaceSysvar($subject, $criteria);
            $from    = $mailtemplate_model->replaceSysvar($row['mail_from'], $criteria);
            $content = $mailtemplate_model->replaceSysvar($row['content'], $criteria);
            
            $headers = array(
                    'from'      => $from,
                    'from_name' => $service['name'],
                    'subject'   => $subject,
            );
            $body = $content;
            //$to_list = implode(', ', $send_to);
            
            $mail_sender->sendBroadcastMail($send_to, $headers, $body);
        }
    }
    
    /** Local Methods **/
    
    /**
     * 下位の回答情報を再帰的に取得する
     * 
     * @param array 回答
     * @return array
     */
    protected function _getChildResponses($rows)
    {
        $returnRows = array();
        foreach ($rows as $row) {
            $db = $this->getAdapter();
            $select = $db->select()
                ->from(array('r' => 't_reply'))
                ->join(array('u' => 'm_user'), 'r.respondent_id=u.id', array('respondent_user_id' => 'user_id', 'respondent_name' => 'name'))
                ->where('r.inquiry_id=?', $row['inquiry_id'])
                ->where('r.parent_id=?', $row['id'])
                ->order('r.reply_datetime ASC')
            ;
            $result = $db->fetchAssoc($select);
            
            if (!empty($result)) {
                $result = $this->_getChildResponses($result);
            }
            
            array_push($returnRows, $row);
            $returnRows = array_merge($returnRows, $result);
        }
        
        return $returnRows;
    }
}