<?php
namespace Manage\Src;

use Dever;

class Doc
{
    private $data;

    public function __construct()
    {
        $this->load();
    }

    public function nav()
    {
        return $this->data['nav'];
    }

    public function info()
    {
        return $this->data['nav'][$this->db];
    }

    public function doc()
    {
        return $this->doc;
    }

    public function menu()
    {
        return $this->data['data'];
    }

    private function load()
    {
        $this->type = Dever::input('type', 'db');

        $this->db = Dever::input('db');

        $type = 'load_' . $this->type;

        $this->$type();
    }

    private function create_nav($list, $num = 0)
    {
        $this->data['nav'] = array();

        $i = 0;
        foreach ($list as $k => $v) {
            if ($v['order'] > $num) {
                if (!$this->db && $i == 0) {
                    $this->db = $k;
                }
                $this->data['nav'][$k] = array
                (
                    'name' => $v['lang'],
                    'link' => Dever::url('doc/view?type=' . $this->type . '&db=' . $k, 'manage'),
                    'class' => $this->db == $k ? 'active' : '',
                );
                $i++;
            }
        }
        if (!$this->data['nav']) {
            Dever::alert('没有该数据项');
        }
    }

    private function load_db()
    {
        $list = Dever::load('manage/project.get');

        $this->create_nav($list);

        if (isset($this->data['nav'][$this->db])) {
            $this->doc = '介绍' . $this->data['nav'][$this->db]['name'] . '项目下的数据结构与对外的数据接口';

            $database = Dever::load('manage/database');
            $data = $database->config($this->db);
            $this->data['data'] = array();

            $table = array
            (
                '方法名' => '参数',
                '查询表中所有数据(all)' => array
                (
                    'option_col' => '可选参数，col换成表的字段',
                ),
                '查询表中一条数据(one)' => array
                (
                    'where_id' => '必填参数，表主键',
                ),
                '插入数据(insert)' => array
                (
                    'add_col' => '必填参数，col换成表的字段',
                ),
                '删除数据(delete)' => array
                (
                    'where_id' => '必填参数，表主键',
                ),
                '更新数据(update)' => array
                (
                    'where_id' => '必填参数，表主键',
                    'set_col' => '必填参数，col换成表的字段',
                ),
            );

            $this->data['data']['api']['name'] = '通用数据接口';
            $this->data['data']['api']['content'] = '<pre>所有数据接口，均使用：Dever::db("项目名/表名")->方法名(参数)调取<br />例如：Dever::db("manage/role")->all(array("option_name" => "超级管理员"))</pre>';

            $this->data['data']['api']['content'] .= Dever::table($table);

            foreach ($data as $k => $v) {
                $this->data['data'][$k]['content'] = '<h3>数据结构：</h3>';
                $this->data['data'][$k]['content'] .= $v['manage']['struct'];
                //$this->data['data'][$k]['name'] = $v['lang'];
                //$this->data['data'][$k]['name'] = $this->db . '_' . $v['name'] . '('.$v['lang'].'表)';
                $this->data['data'][$k]['name'] = $v['name'] . '(' . $v['lang'] . '表)';

                unset($v['request']['list']);

                if (isset($v['request']) && $v['request']) {
                    $this->data['data'][$k]['content'] .= '<h3>数据接口：</h3>';
                    $this->data['data'][$k]['content'] .= Dever::table($v['request']);
                }
            }

            return $this->data['data'];
        }

        return array();
    }

    private function load_mysql()
    {
        $list = array
            (
            'guifan' => array
            (
                'lang' => '规范',
                'order' => 1,
            ),

            'sql' => array
            (
                'lang' => '优化',
                'order' => 1,
            ),

            'example' => array
            (
                'lang' => '样例',
                'order' => 1,
            ),

            'function' => array
            (
                'lang' => '常用函数',
                'order' => 1,
            ),
        );

        $this->create_nav($list);

        if (isset($this->data['nav'][$this->db])) {
            $this->doc = '介绍Mysql' . $this->data['nav'][$this->db]['name'] . '里的一些常见问题';

            $this->data['data'] = array();

            $data['guifan'] = array
            (
                'mm' => array
                (
                    'name' => '命名和编码',
                    'content' => '<pre>
库名、表名、字段名必须使用小写字母，多个单词用“_”分割（例如表名:user_comment）

库名、表名、字段名称禁止使用mysql保留字命名 ，比如：select，insert，order，group，delete，limit等等

建库和建表的编码和字符集分别是utf8和utf8_general_ci

使用dever建立表时，请遵守dever框架规范
					</pre>',
                ),

                'sql' => array
                (
                    'name' => '建库建表',
                    'content' => "<pre>
表类型如果读多写极少（比如文章）可以用myisam；读写都较多或者需要用到事物的情况用innodb;

其它情况两个都可以选择

字段必须有详细注释，并且有多值的字段要列出所有值的含义（比如状态status字段）

字段必须为NOT NULL和设置default值

字段固定长度的短字符用char（例如md5后的密码），长度不固定的用varchar，char或者varchar能满足的不要使用text

大字段类型要慎用（TEXT、BLOB等等）

字段能用int类型都使用int型存储

<pre>例如：
IP可转换成int后存储
日期和时间可用int存储
enum类型可使用tinyint存储</pre>
密码字段不能明文存储

建表就得考虑索引，而不是发现sql慢了才加索引

单个表字段一般情况下最多不能超过30个字段（可将大字段和不常用的字段拆分到新表中）

建表Demo：
					<pre>
CREATE TABLE `user_base` (
`id`  int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户 ID' ,
`username`  char(50) NOT NULL DEFAULT ' ' COMMENT '用户名' ,
`password`  char(32) NOT NULL DEFAULT ' ' COMMENT '密码' ,
`email`  char(50) NOT NULL DEFAULT ' ' COMMENT '电子邮件' ,
`regdate`  int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '注册日期' ,
`last_login_ip`  int(11) NOT NULL DEFAULT 0 COMMENT '最后登录IP' ,
`status`  tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '状态：1正常；2已删除；' ,
PRIMARY KEY (`id`),
UNIQUE INDEX `uniq_username` (`username`) USING BTREE
)
ENGINE=MyISAM
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
COMMENT='用户基本表'
AUTO_INCREMENT=1
					</pre>
					</pre>",
                ),
            );

            if (!isset($data[$this->db])) {
                Dever::alert('没有该数据项');
            }
            $this->data['data'] = $data[$this->db];

            return $this->data['data'];
        }

        return array();
    }

    private function load_api()
    {
        $data = Dever::load('manage/api-getAll');

        if (isset($data['manage'])) {
            unset($data['manage']);
        }

        $keys = array_keys($data);

        $list = array();

        $project = Dever::load('manage/project.get');

        foreach ($keys as $k => $v) {
            if (isset($project[$v])) {
                $list[$v] = $project[$v];
            }
        }

        $this->create_nav($list, -50);

        if (isset($this->data['nav'][$this->db]) && isset($data[$this->db])) {
            $this->doc = '介绍' . $this->data['nav'][$this->db]['name'] . '项目下的对外接口';
            $config = Dever::db('manage/api')->config;
            $type = $config['gettype'];
            $doc = $config['doc'];
            $html = $config['html'];

            $this->data['data'] = array();

            $this->data['data']['api']['name'] = '公共参数说明';
            $this->data['data']['api']['content'] = '<pre>加密共有两种方式：<br />1、请求加密：所有传输参数均要进行加密，通过token加密，加密方法如下：<br />' . $doc . '<br /><br />2、登录加密：由服务端生成signature，然后客户端保存此signature，每次客户端向服务端请求，均需要传输signature，本方式适用移动端登录状态。signature中自带uid。</pre>';

            $this->data['data']['api']['content'] .= $html;
            $this->class = Dever::load('manage/api');
            $url = Dever::url('manage/api.update_col');
            foreach ($data[$this->db] as $k => $v) {

                $one = array
                (
                    'option_api_id' => $v['id'],
                    'option_parent_id' => -1,
                );
                $requestData = Dever::db('manage/api_request')->all($one);
                $responseData = Dever::db('manage/api_response')->all($one);
                $request = $this->class->showTable($requestData, $url, 'api_request');
                $response = $this->class->showTable($responseData, $url, 'api_response');
                $this->data['data'][$k]['content'] = '<h3>接口类型：</h3>';
                $this->data['data'][$k]['content'] .= '<pre>' . ($v['type'] == 1 ? 'get' : 'post') . '</pre>';
                $this->data['data'][$k]['content'] .= '<h3>接口地址：</h3>';

                $this->data['data'][$k]['content'] .= '<pre>' . Dever::url($v['site'], $v['project']) . '</pre>';

                $this->data['data'][$k]['content'] .= '<h3>请求参数：</h3>';
                $this->data['data'][$k]['content'] .= (strip_tags($request) ? $request : '空');

                //$this->data['data'][$k]['content'] .= $this->loadApiData($url, 'request', $requestData));

                $this->data['data'][$k]['content'] .= '<h3>返回参数：</h3>';
                $this->data['data'][$k]['content'] .= $response;

                $this->data['data'][$k]['content'] .= $this->loadApiData($url, 'response', $responseData);

                $v['name'] = '<span class="edit" data-col="name" data-url="'.$url.'" data-id="'.$v['id'].'" data-type="api" >' . $v['name'] . '</span>';

                $this->data['data'][$k]['name'] = $v['name'];
            }

            return $this->data['data'];
        }

        return array();
    }

    private function loadApiData($url, $key, $data, $num = 3, $name = '')
    {
        $num = $num-1;
        return $this->loadApiDataOne($key, $url, $data, $num, $name);
    }

    private function loadApiDataOne($key, $url, $data, $num, $name = '')
    {
        $result = '';
        foreach ($data as $k => $v) {
            if (strpos($v['desc'], 'array') !== false) {
                $one = array
                (
                    'option_parent_id' => $v['id'],
                );
                $all = Dever::db('manage/api_' . $key)->all($one);
                if ($all) {
                    $table = $this->class->showTable($all, $url, 'api_' . $key);

                    if ($name) {
                        $name .= '.';
                        $name = str_replace('..', '.', $name);
                    }
                    $result .= '<h3>'. $name . $v['name'].'：</h3>';
                    $result .= $table;

                    if ($num > 0) {
                        $result .= $this->loadApiData($url, $key, $all, $num, $name . $v['name']);
                    }
                }
            }
        }

        return $result;
    }
}
