<?php

class service{
    
    # 通用型读取数据列表 <带分页> 
    public static function common_query($model, $url, $page, $options = array(), $admin = false){
        Doo::loadModel($model, false, $admin);
        $object = new $model();
        $pager = new DooPager($url, $object->count($options), 20, 6);
        $pager->paginate($page);
        $options['asArray'] = true;
        $lists = $object->limit($pager->limit, null, 'id', $options);
        $output = $pager->totalItem ? $pager->output : '';
        return array(
            'pager' => $output,
            'lists' => $lists
        );
    }
    
    # 读取数据列表并以ID为索引
    public static function common_index_by_id($model, $options = array(), $admin = false){
        Doo::loadModel($model, false, $admin);
        $object = new $model();
        $options['asArray'] = true;
        $lists = $object->find($options);
        $ret = array();
        if ($lists){
            foreach ($lists as $item){
                $ret[$item['id']] = $item;
            }
        }
        return $ret;
    }
    
    # getOne array
    public static function common_get_one($model, $find, $asArray = true, $admin = false){
        Doo::loadModel($model, false, $admin);
        $object = new $model();
        foreach ($find as $field => $value){
            $object->$field = $value;
        }
        $db = $object->getOne(array('asArray' => $asArray));
        if ($db){
            return $db;
        }
        return array();
    }
    
    # count
    public static function common_count($model, $options = array(), $admin = false){
        Doo::loadModel($model, false, $admin);
        $object = new $model();
        return $object->count($options);
    }
    
    # 所有系统模块
    public static function channels($admin = false){       
        $result = service::common_index_by_id('AdminChannel', array('where' => 'status=1'), $admin);
        $result[0] = array('id' => 0, 'name' => '系统设置', 'path' => ROOT_ADMIN, 'status' => 1, 'installed' => 1);
        return $result;
    }

    # 钩子集合 (另: emlog, wordpress, dz的钩子也可参考)
    private static $actions = array();
    
    # 添加钩子
    public static function add_action($hook, $function){
        if(!self::exists_action($hook)){
            self::$actions[$hook] = array();
        }
        if (is_callable($function)){
            self::$actions[$hook][] = $function;
            return true;
        }
        return false;
    }
    
    # 检查钩子
    public static function exists_action($hook){
        return (isset(self::$actions[$hook])) ? self::$actions[$hook] : false;
    }
    
    # 执行钩子
    public static function do_action($hook, $params = null, $res = 0){
        if(isset(self::$actions[$hook])){
            foreach(self::$actions[$hook] as $function){
                if (is_array($params)){
                    $value = call_user_func_array($function, $params);
                }else{
                    $value = call_user_func($function);
                }
            }
            return $value;
        }else{
            if ($res){
                return $params[$res];
            }
        }
        return false;
    }
    
    # get option
    public static function get_option($name){
        Doo::loadModel('AdminOption', false, true);
        $ao = new AdminOption();
        $ao->option_name = $name;
        $db = $ao->getOne(array('asArray' => true));
        return $db ? $db['option_value'] : '';
    }
    
    # 表名 => 模块名
    public static function model_name($temptbl){
        $classname = '';
        for($i=0;$i<strlen($temptbl);$i++) {
            if($i==0) {
                $classname .= strtoupper($temptbl[0]);
            }else if($temptbl[$i]=='_' || $temptbl[$i]=='-' || $temptbl[$i]=='.' ) {
                $classname .= strtoupper( $temptbl[ ($i+1) ] );
                $arr = str_split($temptbl);
                array_splice($arr, $i, 1);
                $temptbl = implode('', $arr);
            }else {
                $classname .= $temptbl[$i];
            }
        }
        return $classname;
    }
    
    # 二维码合成
    public static function qrcode($user, $wx, $qrcodeParams){
        /*
         * $qrcodeSize = 带参数二维码的大小
         * $qrcodeX = 二维码在背景图片的X偏移
         * $qrcodeY = 二维码在背景图片的Y偏移
         * $faceX = 头像在背景图片的X偏移
         * $faceY = 头像在背景图片的Y偏移
         * $fontSize = 文字在背景图片的大小
         * $fontColor = 文字在背景图片的显示颜色
         * $textX = 文字在背景图片的X偏移
         * $textY = 文字在背景图片的Y偏移
         */
        list($qrcodeSize, $qrcodeX, $qrcodeY, $faceX, $faceY, $fontSize, $fontColor, $textX, $textY) = explode('|', $qrcodeParams);
        $ctx = stream_context_create(array(
            'http' => array(
                'timeout' => 1 // s
            )
        ));
        $cachePath = Doo::conf()->SITE_PATH.'cache/qrcode/';                
        # 下载头像
        $face = str_replace('/0', '/64', $user->headimgurl);
        $logo = 'logo_'.$user->id.'.jpg';
        $data = file_get_contents($face, 0, $ctx);
        file_put_contents($cachePath.$logo, $data);
        # 下载二维码
        $db = $wx->getQRCode($user->id, 2);
        $url = $wx->getQRUrl($db['ticket']);
        $data = file_get_contents($url, 0, $ctx);
        $qrcode = 'ticket_'.$user->id.'.jpg';
        file_put_contents($cachePath.$qrcode, $data);
        # 背景
        $bg = 'card.jpg';
        # 二维码大小
        $qrcode_thumb = 'ticket_'.$user->id.'_340x340.jpg';
        Doo::loadHelper('DooGdImage');
        $GD = new DooGdImage($cachePath, $cachePath);
        $GD->generatedQuality = 85;
        $GD->generatedType = 'jpg';
        $GD->thumbSuffix = '_340x340';
        $GD->createThumb($qrcode, $qrcodeSize, $qrcodeSize);
        $thumb = $cachePath.$qrcode_thumb;
        # 把二维码合成到背景中
        $GD->waterMarkImage($bg, $thumb, $qrcodeX, $qrcodeY, 'bg_qrcode_'.$user->id);
        $bg_qrcode = 'bg_qrcode_'.$user->id.'.jpg';
        # 把头像合成到新背景中
        $GD->waterMarkImage($bg_qrcode, $cachePath.$logo, $faceX, $faceY, 'bg_qrcode_logo_'.$user->id);
        $bg_qrcode_logo = 'bg_qrcode_logo_'.$user->id.'.jpg';
        # 把昵称合成到新背景中
        $GD->setFont('hei.ttf', $cachePath);
        $GD->text($bg_qrcode_logo, $user->nickname, $fontSize, $fontColor, array($textX, $textY), 'qrcode_'.$user->id);
        @unlink($cachePath.$logo);
        @unlink($cachePath.$qrcode);
        @unlink($thumb);
        @unlink($cachePath.$bg_qrcode);
        @unlink($cachePath.$bg_qrcode_logo);
        # 发送到微信
        $finally = $cachePath.'qrcode_'.$user->id.'.jpg';        
        $media = $wx->uploadMedia(array(
            'media' => '@'.$finally
        ), 'image');
        if ($media){
            $media_id = $media['media_id'];
            $message = $wx->sendCustomMessage(array(
                'touser' => $user->openid,
                'msgtype' => 'image',
                'image' => array(
                    'media_id' => $media_id
                )
            ));
            if ($message){
                echo 'ok';
                @unlink($finally);
            }else{
                echo '发送失败2';
            }
        }else{
            echo '发送失败1';
        }
    }
    
    # 锁定关系
    public static function lock_link($fromUser, $currentUser, $wx, $from = 0){        
        # 检查是否已锁定关系
        Doo::loadModel('ShopLinks');
        Doo::loadModel('ShopUsers'); 
        $SL = new ShopLinks();
        $SL->userid = $currentUser->id;
        $db = $SL->getOne();
        if ($db){
            # 已锁定
        }else{
            # 开始锁定
            $UP = new ShopLinks();
            $UP->userid = $fromUser->id;
            $rs = $UP->getOne();
            $SL->dateline = time();
            $SL->userid_value = $currentUser->nickname;
            $level = array();
            if ($fromUser->type == 1 || $fromUser->type == 2){
                $SL->level3 = $fromUser->id;
                $SL->openid3 = $fromUser->openid;
                $SL->level2 = $rs->level3;
                $SL->openid2 = $rs->openid3;
                $SL->level1 = $rs->level2;  
                $SL->openid1 = $rs->openid2;
                $level = array(
                    $fromUser->openid, $rs->openid3, $rs->openid2
                );
                $fid = $fromUser->id;
                $fid_value = $fromUser->nickname;
            }else{
                $SL->level3 = $rs->level3;
                $SL->openid3 = $rs->openid3;
                $SL->level2 = $rs->level2;
                $SL->openid2 = $rs->openid2;
                $SL->level1 = $rs->level1;
                $SL->openid1 = $rs->openid1;
                $level = array(
                    $rs->openid3, $rs->openid2, $rs->openid1
                );
                $fid = $rs->level3;
                $fidObj = new ShopUsers();
                $fidObj->id = $rs->level3;
                $fidOne = $fidObj->getOne();
                $fid_value = $fidOne->nickname;
            }
            $ceo = '';
            if ($fromUser->type == 2){
                $SL->ceo = $fromUser->id;
                $SL->ceoopenid = $fromUser->openid;
                $ceo = $fromUser->openid;
                $partner = $fromUser->id;
                $partner_value = $fromUser->nickname;
            }else{
                $SL->ceo = $rs->ceo;
                $SL->ceoopenid = $rs->ceoopenid;
                $ceo = $rs->ceoopenid;
                $partner = $rs->ceo;
                $partnerObj = new ShopUsers();
                $partnerObj->id = $rs->ceo;
                $partnerOne = $partnerObj->getOne();
                $partner_value = $partnerOne->nickname;
            }
            if ($lastid = $SL->insert()){
                # 更新当前用户信息
                $SU = new ShopUsers();
                $SU->id = $currentUser->id; 
                $SU->comefrom = ($from == 0 ? '扫码' : '分享').'自'.$fromUser->nickname.'('.$fromUser->id.')';
                $SU->fid = $fid;
                $SU->fid_value = $fid_value;
                $SU->partner = $partner;
                $SU->partner_value = $partner_value;
                $SU->dateline = time();
                $SU->update();
                # 写入积分
                $jifen = intval(service::get_option('qrcodeJifen'));
                Doo::loadModel('ShopJifen');
                $JF = new ShopJifen();
                $JF->openid2 = $currentUser->openid;
                $JFC = $JF->getOne();
                if($JFC){
                    #已关注过
                }else{
                    #没关注过
                    $JF->uid1 = $fromUser->id;
                    $JF->uid1_value = $fromUser->nickname;
                    $JF->openid1 = $fromUser->openid;
                    $JF->uid2 = $currentUser->id;
                    $JF->uid2_value = $currentUser->nickname;
                    $JF->openid2 = $currentUser->openid;
                    $JF->jifen = $jifen;
                    $JF->dateline = time();
                    if($lsid = $JF->insert()){
                        $U = new ShopUsers();
                        $U->id = $fromUser->id;
                        $U->jifen = $fromUser->jifen + $jifen;
                        $U->update();
                    }
                }           
                # 发送客服消息
                $content = '【'.$currentUser->nickname.'】通过'.($from == 0 ? '扫描二维码' : '分享链接').'，加入您的团队';
                foreach ($level as $id){
                    if ($id){
                        service::wx_send($wx, $id, $content);
                    }
                }
                if ($ceo){
                    service::wx_send($wx, $ceo, $content);
                }
            }
        }
    }
    
    # 没有上线时锁定关系
    public static function lock_is_me($user){
        Doo::loadModel('ShopLinks');
        $SL = new ShopLinks();
        $SL->userid = $user->id;
        $db = $SL->getOne();
        if ($db){
            # 已锁定
        }else{
            # 开始锁定
            $SL->dateline = time();
            $SL->userid_value = $user->nickname;
            $SL->insert();
        }
    }
    
    # 发送客服消息
    public static function wx_send($wx, $openid, $content){
        $message = $wx->sendCustomMessage(array(
            'touser' => $openid,
            'msgtype' => 'text',
            'text' => array(
                'content' => $content
            )
        ));
        if ($message){
            return true;
        }
        return false;
    }
}
