<?php
/**
 * model类从baseModel类继承而来，每个模块的model对象从model类集成。
 * 您可以对baseModel类进行扩展，扩展的逻辑可以定义在这个文件中。
 *
 * This model class extends from the baseModel class and extened by every module's model. 
 * You can extend the baseModel class by change this file.
 *
 * @package framework
 *
 * The author disclaims copyright to this source code.  In place of
 * a legal notice, here is a blessing:
 *
 *  May you do good and not evil.
 *  May you find forgiveness for yourself and forgive others.
 *  May you share freely, never taking more than you give.
 */
include FRAME_ROOT . '/base/model.class.php';
class model extends baseModel
{
    /**
     * Delete one record.
     *
     * @param  string    $table  the table name
     * @param  string    $id     the id value of the record to be deleted
     * @access public
     * @return void
     */
    public function delete($table, $id)
    {
        $this->dao->update($table)->set('deleted')->eq(1)->where('id')->eq($id)->exec();
        $object = trim(substr($table, strrpos($table, '_') + 1), '`');
        $this->loadModel('action')->create($object, $id, 'deleted', '', $extra = ACTIONMODEL::CAN_UNDELETED);
    }

    /**
     * Build menu of a module.
     *
     * @param  string $moduleName
     * @param  string $methodName
     * @param  string $params
     * @param  string $label
     * @param  object $data
     * @param  string $type
     * @param  string $misc
     * @param  bool   $li
     * @access public
     * @return string
     */
    public function buildMenu($moduleName, $methodName, $params, $label, $data, $type = 'browse', $misc = '', $li = false)
    {
        $appName = $this->appName;
        if(strpos($moduleName, '.') !== false) list($appName, $moduleName) = explode('.', $moduleName);

        if(strpos($methodName, '_') !== false && strpos($methodName, '_') > 0) list($module, $method) = explode('_', $methodName);

        if(empty($module)) $module = $moduleName;
        if(empty($method)) $method = $methodName;

        if(!commonModel::hasPriv($appName . '.' . $module, $method)) return '';

        if($this->app->isBiz)
        {
            static $actions;
            if(empty($actions)) $actions = $this->dao->select('*')->from(TABLE_WORKFLOWACTION)->where('module')->eq($moduleName)->andWhere('buildin')->eq('1')->andWhere('status')->eq('enable')->fetchAll('action');
        }

        $enabled = true;
        if(isset($actions[$methodName]))
        {
            $action = $actions[$methodName];

            if($action->extensionType == 'override') return $this->loadModel('flow')->buildActionMenu($appName . '.' . $moduleName, $action, $data, $type);

            $conditions = json_decode($action->conditions);
            if($action->extensionType == 'extend')
            {
                $label = $action->name;
                if($conditions) $enabled = $this->loadModel('flow')->checkConditions($conditions, $data);
            }
            else
            {
                if(method_exists($this, 'isClickable')) $enabled = $this->isClickable($module, $method, $data);
            }
        }
        else
        {
            if(method_exists($this, 'isClickable')) $enabled = $this->isClickable($module, $method, $data);
        }

        if($enabled) $enabled = commonModel::checkPrivByVars($module, $method, $params);

        if($enabled)
        {
            $link = helper::createLink($appName . '.' . $module, $method, $params);
            $html = html::a($link, $label, $misc);
            if($type == 'browse' && $li) $html = '<li>' . $html . '</li>';

            return $html;
        }
        else
        {
            if($type == 'view') return '';
            if($type == 'browse' && $li) return '';

            return html::a('javascript:;', $label, "class='disabled'");
        }
    }

    /**
     * Build menu of actions created by workflow action.
     *
     * @param  string $module
     * @param  int    $data
     * @param  string $type         browse | view
     * @param  string $show         direct | dropdownlist
     * @access public
     * @return string
     */
    public function buildFlowMenu($module, $data, $type = 'browse', $show = '')
    {
        if(!$this->app->isBiz) return '';

        $appName    = $this->appName;
        $moduleName = $module;
        if(strpos($module, '.') !== false) list($appName, $moduleName) = explode('.', $module);

        static $actions;
        static $relations;
        if(empty($actions))   $actions   = $this->dao->select('*')->from(TABLE_WORKFLOWACTION)->where('module')->eq($moduleName)->andWhere('buildin')->eq('0')->andWhere('status')->eq('enable')->orderBy('order_asc')->fetchAll();
        if(empty($relations)) $relations = $this->dao->select('next, actions')->from(TABLE_WORKFLOWRELATION)->where('prev')->eq($moduleName)->fetchPairs();

        $this->loadModel('flow');

        $approvalProgressMenu = '';
        if($type == 'view' && !empty($this->config->openedApproval) && commonModel::hasPriv('approval', 'progress'))
        {
            $flow = $this->loadModel('workflow', 'flow')->getByModule($moduleName);
            if($flow->approval == 'enabled' && !empty($data->approval))
            {
                $approvalProgressMenu .= "<div class='divider'></div>";
                $approvalProgressMenu .= html::a(helper::createLink('approval', 'progress', "approvalID={$data->approval}"), $this->lang->flow->approvalProgress, "class='btn' data-toggle='modal'");
            }
        }

        $menu = '';
        if($show)
        {
            foreach($actions as $action)
            {
                if(strpos($action->position, $type) === false || $action->show != $show) continue;

                $menu .= $this->flow->buildActionMenu($appName . '.' . $moduleName, $action, $data, $type, $relations);
            }

            if($approvalProgressMenu) $menu .= $approvalProgressMenu;
        }
        else
        {
            $dropdownMenu = '';
            foreach($actions as $action)
            {
                if(strpos($action->position, $type) === false) continue;

                if($type == 'view' || $action->show == 'direct')         $menu         .= $this->flow->buildActionMenu($appName . '.' . $moduleName, $action, $data, $type, $relations);
                if($type == 'browse' && $action->show == 'dropdownlist') $dropdownMenu .= $this->flow->buildActionMenu($appName . '.' . $moduleName, $action, $data, $type, $relations);
            }

            if($approvalProgressMenu) $menu .= $approvalProgressMenu;

            if($type == 'browse' && $dropdownMenu)
            {
                $menu .= "<div class='dropdown'><a href='javascript:;' data-toggle='dropdown'>{$this->lang->more}<span class='caret'> </span></a>";
                $menu .= "<ul class='dropdown-menu pull-right'>{$dropdownMenu}</ul></div>";
            }
        }

        return $menu;
    }

    /**
     * Process status of an object according to its subStatus.
     *
     * @param  string $module   order | contract | purchasecontract | customer | provider | contact | leads | product | invoice | feedback
     * @param  object $record   a record of above modules.
     * @access public
     * @return string
     */
    public function processStatus($module, $record)
    {
        if(!$this->app->isBiz or empty($record->subStatus)) return zget($this->lang->$module->statusList, $record->status);

        return $this->loadModel('workflowfield', 'flow')->processSubStatus($module, $record);
    }

    /**
     * Process workflow export data.
     *
     * @param  object    $data
     * @access public
     * @return object
     */
    public function processExportData($data)
    {
        if(!$this->app->isBiz) return $data;

        return $this->loadModel('workflowfield', 'flow')->processExportData($data);
    }

    /**
     * Process workflow export options.
     *
     * @param  object    $data
     * @access public
     * @return object
     */
    public function processExportOptions($data)
    {
        if(!$this->app->isBiz) return $data;

        return $this->loadModel('workflowfield', 'flow')->processExportOptions($data);
    }

    /**
     * Process workflow import data.
     *
     * @param  object    $data
     * @access public
     * @return object
     */
    public function processImportData($data)
    {
        if(!$this->app->isBiz) return $data;

        return $this->loadModel('workflowfield', 'flow')->processImportData($data);
    }

    /**
     * Get flow extend fields.
     *
     * @access public
     * @return array
     */
    public function getFlowExtendFields()
    {
        if(!$this->app->isBiz) return array();

        return $this->loadModel('flow')->getExtendFields($this->app->getModuleName(), $this->app->getMethodName());
    }

    /**
     * Set workflow export fields.
     *
     * @access public
     * @return string
     */
    public function getFlowExportFields()
    {
        if(!$this->app->isBiz) return array();

        return $this->loadModel('workflowfield', 'flow')->getExportFields($this->app->getModuleName());
    }

    /**
     * Execute Hooks.
     *
     * @param  int    $objectID
     * @param  bool   $createAction
     * @access public
     * @return void
     */
    public function executeHooks($objectID, $createAction = true)
    {
        if(!$this->app->isBiz) return false;

        $moduleName = $this->app->getModuleName();
        $methodName = $this->app->getMethodName();

        $action = $this->loadModel('workflowaction', 'flow')->getByModuleAndAction($moduleName, $methodName);
        if(empty($action) or $action->extensionType == 'none') return false;

        $this->loadModel('file');
        if($this->post->uid) $this->file->updateObjectID($this->post->uid, $objectID, $moduleName);
        $fields = $this->workflowaction->getFields($moduleName, $action->action, false);
        foreach($fields as $field)
        {
            if($field->control == 'file' && $field->show && !$field->readonly)
            {
                $this->file->saveUpload($moduleName, $objectID, $field->field, $field->field, $field->field);
            }
        }

        $flow = $this->loadModel('workflow', 'flow')->getByModule($moduleName);
        if($flow && $action) return $this->loadModel('workflowhook', 'flow')->execute($flow, $action, $objectID, $createAction);
    }
}
