<?php

class ACMS_POST_Approval_Request extends ACMS_POST_Approval
{
    function post()
    {
        $DB         = DB::singleton(dsn());
        $Approval   = $this->extract('approval');
        if ( !($rvid    = $Approval->get('rvid')) ) return false;

        $workflowPoint  = approvalWorkflowPublicPoint(BID, CID);
        $currentPoint   = approvalRevisionPublicPoint(EID, $rvid);
        $point          = approvalUserPoint(BID);

        if ( enableParallelApproval(BID, CID) && $workflowPoint <= $currentPoint + $point ) {
            $Approval->setMethod('approvalPoint', 'overpoint', false);
        }
        if ( !sessionWithApprovalRequest() ) {
            $Approval->setMethod('approvalRequest', 'operator', false);
        }
        $Approval->validate(new ACMS_Validator());

        if ( $this->Post->isValidAll() ) {
            $receiver   = $Approval->get('receiver');
            $comment    = $Approval->get('request_comment');
            $req_group  = $Approval->get('current_group');
            $deadline   = $Approval->get('deadline_date');
            $ugid       = null;
            $uid        = null;

            if ( preg_match('/\d:\d/', $receiver) ) {
                list($ugid, $uid) = preg_split('@:@', $receiver, 2, PREG_SPLIT_NO_EMPTY);
            }
            $To     = '';
            $type   = 'series';

            if ( empty($uid) ) {
                if ( editionIsEnterprise() ) {
                    $workflow = loadWorkflow(BID, CID);
                    $type = $workflow->get('workflow_type');
                    $cid = $workflow->get('workflow_category_id');
                    if (empty($cid)) {
                        $cid = null;
                    } else {
                        $cid = intval($cid);
                    }

                    // 並列承認
                    if ($type === 'parallel') {

                        // すでに承認作業済みのユーザを除去
                        $exceptUser = array();
                        $SQL = SQL::newSelect('approval_notification');
                        $SQL->addSelect('notification_request_user_id');
                        $SQL->addWhereOpr('notification_type', 'request');
                        $SQL->addWhereOpr('notification_rev_id', $rvid);
                        $SQL->addWhereOpr('notification_entry_id', EID);
                        $SQL->addWhereOpr('notification_blog_id', BID);
                        $all    = $DB->query($SQL->get(dsn()), 'all');
                        foreach ( $all as $row ) {
                            $exceptUser[] = $row['notification_request_user_id'];
                        }

                        $SQL = SQL::newSelect('workflow_usergroup', 'wug');
                        $SQL->addLeftJoin('usergroup_user', 'usergroup_id', 'usergroup_id', 'ugu', 'wug');
                        $SQL->addLeftJoin('user', 'user_id', 'user_id', 'u', 'ugu');
                        $SQL->addSelect('user_mail');
                        $SQL->addSelect('user_name');
                        $SQL->addWhereOpr('user_status', 'open');
                        $SQL->addWhereOpr('user_id', SUID, '<>', 'AND', 'u');
                        $SQL->addWhereOpr('workflow_blog_id', BID);
                        $SQL->addWhereOpr('workflow_category_id', $cid);
                        $SQL->addWhereNotIn('user_id', $exceptUser, 'AND', 'u');

                        $mail   = $DB->query($SQL->get(dsn()), 'all');
                        $mail_  = array();
                        foreach ( $mail as $addr ) {
                            $mail_[] = $addr['user_mail'];
                        }
                        $To     = $mail_;

                    // 直列承認
                    } else {
                        $uid = null;
                        $SQL = SQL::newSelect('usergroup_user', 't_usergroup_user');
                        $SQL->addLeftJoin('user', 'user_id', 'user_id', 't_user', 't_usergroup_user');
                        $SQL->addSelect('user_mail');
                        $SQL->addSelect('user_name');
                        $SQL->addWhereOpr('user_status', 'open');

                        if (empty($ugid)) {
                            $lastGroup  = $workflow->getArray('workflow_last_group');
                            $SQL->addWhereIn('usergroup_id', $lastGroup);
                        } else {
                            $SQL->addWhereOpr('usergroup_id', $ugid);
                        }

                        $mail = $DB->query($SQL->get(dsn()), 'all');
                        $mail_ = array();
                        foreach ( $mail as $addr ) {
                            $mail_[] = $addr['user_mail'];
                        }
                        $To = $mail_;
                    }
                } else if ( editionIsProfessional() ) {
                    $uid    = null;
                    $ugid   = null;
                    $SQL    = SQL::newSelect('user');
                    $SQL->addLeftJoin('blog', 'blog_id', 'user_blog_id');
                    if ( config('blog_manage_approval') == 'on' ) {
                        ACMS_Filter::blogTree($SQL, BID, 'self-ancestor');
                    } else {
                        $SQL->addWhereOpr('user_blog_id', BID);
                    }
                    ACMS_Filter::blogStatus($SQL);
                    $SQL->addWhereIn('user_auth', array('editor', 'administrator'));
                    $SQL->addWhereOpr('user_status', 'open');

                    $mail   = $DB->query($SQL->get(dsn()), 'all');
                    $mail_  = array();
                    foreach ( $mail as $addr ) {
                        $mail_[] = $addr['user_mail'];
                    }
                    $To     = $mail_;
                }
            } else {
                if ( editionIsProfessional() ) $ugid = null;
                $To     = ACMS_RAM::userMail($uid);
            }

            //-----------
            // Send Mail
            if ( 1
                and $To
                and $subjectTpl = findTemplate(config('mail_approval_tpl_subject'))
                and $bodyTpl    = findTemplate(config('mail_approval_tpl_body'))
            ) {
                $SQL = SQL::newSelect('entry_rev');
                $SQL->addWhereOpr('entry_id', EID);
                $SQL->addWhereOpr('entry_rev_id', $rvid);
                $rev = $DB->query($SQL->get(dsn()), 'row');

                $Approval->setField('request_user', ACMS_RAM::userName(SUID));
                $Approval->setField('approval', 'request');
                $Approval->setField('approval2', 'request');
                $Approval->setField('approval3', 'request');
                $Approval->setField('approval4', 'request');
                $Approval->setField('entryTitle', $rev['entry_title']);
                $Approval->setField('entryStatus', ACMS_RAM::entryStatus(EID));
                $Approval->setField('version', $rev['entry_rev_memo']);
                $Approval->setField('revisionUrl', acmsLink(array(
                    'protocol'  => SSL_ENABLE ? 'https' : 'http',
                    'bid'   => BID,
                    'cid'   => CID,
                    'eid'   => EID,
                    'tpl'   => 'ajax/revision-preview.html',
                    'query' => array('rvid' => $rvid),
                ), false));

                $workflowPoint  = approvalWorkflowPublicPoint(BID, CID);
                $currentPoint   = approvalRevisionPublicPoint(EID, $rvid);
                $point          = approvalUserPoint(BID);

                $Approval->setField('approvalType', $type);
                $Approval->setField('workflowPoint', $workflowPoint);
                $Approval->setField('currentPoint', ($currentPoint + $point));
                $Approval->setField('approvalPoint', $workflowPoint - ($currentPoint + $point));

                $subject    = Common::getMailTxt($subjectTpl, $Approval);
                $body       = Common::getMailTxt($bodyTpl, $Approval);

                $to = is_array($To) ? implode(', ', $To) : $To;
                $from = getApprovalFrom(SUID);
                $bcc = implode(', ', configArray('mail_approval_bcc'));

                $send = true;
                if ( HOOK_ENABLE ) {
                    $data = array(
                        'type'      => 'request',
                        'from'      => array($from),
                        'to'        => $To,
                        'subject'   => $subject,
                        'bcc'       => configArray('mail_approval_bcc'),
                        'body'      => $body,
                        'data'      => $Approval,
                    );
                    $Hook   = ACMS_Hook::singleton();
                    $Hook->call('approvalNotification', array($data, & $send));
                }
                if ( $send !== false ) {
                    try {
                        $mailer = Mailer::init();
                        $mailer->setFrom($from)
                            ->setTo($to)
                            ->setBcc($bcc)
                            ->setSubject($subject)
                            ->setBody($body);
                        if ($bodyHtmlTpl = findTemplate(config('mail_approval_tpl_body_html'))) {
                            $bodyHtml = Common::getMailTxt($bodyHtmlTpl, $Approval);
                            $mailer = $mailer->setHtml($bodyHtml);
                        }
                        $mailer->send();
                    } catch ( Exception $e  ) {
                        throw $e;
                    }
                }

                // 並列承認
                if ( $type == 'parallel' ) {
                    $ugid   = null;
                    $uid    = null;
                }

                $userGroup = array();
                if ( $ugid === '0' ) {
                    $workflow = loadWorkflow(BID, CID);
                    $userGroup  = $workflow->getArray('workflow_last_group');
                } else {
                    $userGroup[] = $ugid;
                }

                //---------
                // Save DB
                $apid   = $DB->query(SQL::nextval('approval_id', dsn()), 'seq');

                foreach ( $userGroup as $ugid ) {
                    $SQL    = SQL::newInsert('approval');
                    $SQL->addInsert('approval_id', $apid);
                    $SQL->addInsert('approval_type', 'request');
                    $SQL->addInsert('approval_method', $type);
                    $SQL->addInsert('approval_datetime', date('Y-m-d H:i:s', REQUEST_TIME));
                    $SQL->addInsert('approval_deadline_datetime', $deadline.' 00:00:00');
                    $SQL->addInsert('approval_comment', $comment);
                    $SQL->addInsert('approval_receive_usergroup_id', $ugid);
                    $SQL->addInsert('approval_receive_user_id', $uid);
                    $SQL->addInsert('approval_request_usergroup_id', $req_group);
                    $SQL->addInsert('approval_request_user_id', SUID);
                    $SQL->addInsert('approval_revision_id', $rvid);
                    $SQL->addInsert('approval_entry_id', EID);
                    $SQL->addInsert('approval_blog_id', BID);
                    $DB->query($SQL->get(dsn()), 'exec');
                }

                //------------------------
                // Update Revision Status
                $SQL    = SQL::newUpdate('entry_rev');
                $SQL->addUpdate('entry_rev_status', 'in_review');
                // 並列承認
                if ( $type == 'parallel' ) {
                    $currentPoint = approvalRevisionPublicPoint(EID, $rvid);
                    $point        = approvalUserPoint(BID);

                    $SQL->addUpdate('entry_approval_public_point', $currentPoint + $point);
                }
                $SQL->addWhereOpr('entry_id', EID);
                $SQL->addWhereOpr('entry_rev_id', $rvid);
                $DB->query($SQL->get(dsn()), 'exec');

                //---------------------
                // Update Notification

                // 並列承認
                $exceptUser = array();
                if ( $type == 'parallel' ) {
                    $SQL    = SQL::newSelect('approval_notification');
                    $SQL->addSelect('notification_request_user_id');
                    $SQL->addWhereOpr('notification_type', 'request');
                    $SQL->addWhereOpr('notification_rev_id', $rvid);
                    $SQL->addWhereOpr('notification_entry_id', EID);
                    $SQL->addWhereOpr('notification_blog_id', BID);
                    $all    = $DB->query($SQL->get(dsn()), 'all');
                    foreach ( $all as $row ) {
                        $exceptUser[] = $row['notification_request_user_id'];
                    }
                }

                $SQL    = SQL::newDelete('approval_notification');
                $SQL->addWhereOpr('notification_type', 'reject');
                $SQL->addWhereOpr('notification_entry_id', EID);
                $SQL->addWhereOpr('notification_blog_id', BID);
                $DB->query($SQL->get(dsn()), 'exec');

                $SQL    = SQL::newDelete('approval_notification');
                $SQL->addWhereOpr('notification_rev_id', $rvid);
                $SQL->addWhereOpr('notification_entry_id', EID);
                $SQL->addWhereOpr('notification_blog_id', BID);
                $DB->query($SQL->get(dsn()), 'exec');

                foreach ( $userGroup as $ugid ) {
                    $SQL    = SQL::newInsert('approval_notification');
                    $SQL->addInsert('notification_rev_id', $rvid);
                    $SQL->addInsert('notification_entry_id', EID);
                    $SQL->addInsert('notification_blog_id', BID);
                    $SQL->addInsert('notification_approval_id', $apid);
                    $SQL->addInsert('notification_receive_user_id', $uid);
                    $SQL->addInsert('notification_receive_usergroup_id', $ugid);
                    $SQL->addInsert('notification_request_user_id', SUID);
                    $SQL->addInsert('notification_type', 'request');
                    $SQL->addInsert('notification_except_user_ids', implode(',', $exceptUser));
                    $SQL->addInsert('notification_datetime', date('Y-m-d H:i:s', REQUEST_TIME));

                    $DB->query($SQL->get(dsn()), 'exec');
                }
            }
        }
        return $this->Post;
    }
}
