<?php
/**
 * The model file of art module of ZenTaoPMS.
 * @copyright   Copyright 2009-2023 禅道软件（青岛）有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
 * @license     ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
 * @author      Sun Guangming<sunguangming@easycorp.ltd>
 * @package     art
 * @link        https://www.zentao.net
 */
class artModel extends model
{
    /**
     * 获取ART名称列表。
     * get art pairs.
     *
     * @param  string $status
     * @access public
     * @return array|false
     */
    public function getPairs($status = '')
    {
        return $this->dao->select('id,name')->from(TABLE_ART)->where('deleted')->eq('0')->beginIF($status)->andWhere('status')->eq($status)->fi()->fetchPairs();
    }

    /**
     * 获取ART列表。
     * Get the list of art.
     *
     * @param  string $status
     * @param  string $orderBy
     * @access public
     * @return array
     */
    public function getList($status = 'normal', $orderBy = 'id_desc'): array
    {
        $artList = $this->dao->select('*')->from(TABLE_ART)
            ->where('deleted')->eq('0')
            ->beginIF($status != 'all')
            ->andWhere('status')->eq($status)
            ->fi()
            ->orderBy($orderBy)
            ->fetchAll();

        $account    = $this->app->user->account;
        $userTeam   = $this->loadModel('team')->getByAccount($account);
        $hasPiPairs = $this->loadModel('pi')->getArtPairs();
        foreach($artList as $id => $art)
        {
            if(!$this->checkAccess($art, $userTeam, $account))
            {
                unset($artList[$id]);
                continue;
            }

            if(isset($hasPiPairs[$art->id])) $artList[$id]->hasPI = true;
        }

        return $artList;
    }

    /**
     * 创建ART。
     * Create art.
     *
     * @param  object    $art
     * @access public
     * @return int|false
     */
    public function create($art)
    {
        $art->createdBy = $this->app->user->account;

        $this->dao->insert(TABLE_ART)->data($art)
            ->batchCheck($this->config->art->create->requiredFields, 'notempty')
            ->check('name', 'unique')
            ->autoCheck()
            ->exec();

        if(dao::isError()) return false;

        return $this->dao->lastInsertID();
    }

    /**
     * 编辑ART。
     * Update art.
     *
     * @param  int         $artID
     * @param  object      $art
     * @access public
     * @return array|false
     */
    public function update($artID, $art)
    {
        $oldArt = $this->fetchByID($artID);
        $this->dao->update(TABLE_ART)->data($art)
            ->batchCheck($this->config->art->edit->requiredFields, 'notempty')
            ->checkIF(!empty($art->name), 'name', 'unique', "id != $artID")
            ->autoCheck()
            ->where('id')->eq($artID)
            ->exec();

        if(dao::isError()) return false;

        return common::createChanges($oldArt, $art);
    }

    /**
     * 关闭ART。
     * Close ART.
     *
     * @param  int    $id
     * @access public
     * @return bool
     */
    public function close($id): bool
    {
        $ART = new stdclass();
        $ART->status     = 'closed';
        $ART->closedBy   = $this->app->user->account;
        $ART->closedDate = helper::today();

        $this->dao->update(TABLE_ART)->data($ART)
            ->where('id')->eq($id)
            ->exec();

        $this->loadModel('action')->create('art', $id, 'closed', $this->post->comment);
        return !dao::isError();
    }

    /**
     * 激活ART。
     * Activate ART.
     *
     * @param  int    $id
     * @access public
     * @return bool
     */
    public function activate($id): bool
    {
        $ART = new stdclass();
        $ART->status        = 'normal';
        $ART->activatedBy   = $this->app->user->account;
        $ART->activatedDate = helper::today();

        $this->dao->update(TABLE_ART)->data($ART)
            ->where('id')->eq($id)
            ->exec();

        $this->loadModel('action')->create('art', $id, 'activated', $this->post->comment);
        return !dao::isError();
    }

    /**
     * 检查当前用户是否有权限访问。
     * Check the access of the current user.
     *
     * @param  object $art
     * @param  array  $userTeam
     * @param  string $account
     * @access public
     * @return bool
     */
    public function checkAccess($art, $userTeam, $account): bool
    {
        if($this->app->user->admin) return true;
        if($art->acl == 'open')     return true;

        $canAccess = false;

        /* 创建人、团队成员、RTE、产品经理、业务负责人、系统架构师、白名单成员可访问。*/
        if($account == $art->createdBy) $canAccess = true;
        if($art->team && array_intersect(explode(',', $art->team), $userTeam)) $canAccess = true;
        if($art->RTE == $account) $canAccess = true;
        if($art->PO && in_array($account, explode(',', $art->PO))) $canAccess = true;
        if($art->manager && in_array($account, explode(',', $art->manager))) $canAccess = true;
        if($art->architect && in_array($account, explode(',', $art->architect))) $canAccess = true;
        if($art->whitelist && in_array($account, explode(',', $art->whitelist))) $canAccess = true;

        return $canAccess;
    }

    /**
     * 检查操作按钮是否可点。
     * Check if the operation button is clickable.
     *
     * @param  object $art
     * @param  string $action
     * @access public
     * @return bool
     */
    public static function isClickable($art, $action): bool
    {
        if($art->deleted == '1') return false;

        $action = strtolower($action);

        if($action == 'createpi') return $art->status != 'closed';
        if($action == 'delete')   return empty($art->hasPI);
        if($action == 'close')    return $art->status != 'closed';
        if($action == 'activate') return $art->status == 'closed';

        return true;
    }
}
