Client.class.php 9.46 KB
<?php
defined('USE_PUSH') || die();

/**
 * 向客户端推送的使用类
 * 
 * @name Lib_Push_Client
 * @package lib/push
 * @copyright yoho.inc
 * @version 4.0 (2013-12-06 10:51:22)
 * @author fei.hong <fei.hong@yoho.cn>
 * @since 0.1
 */
class Lib_Push_Client
{
    /***推送类型***/
    const PUSH_TYPE_SYSTEM = 'system';   // 推送类型: 系统
    const PUSH_TYPE_COMMENT = 'comment'; // 推送类型: 评论
    const PUSH_TYPE_FOLLOW = 'follow';   // 推送类型: 关注
    const PUSH_TYPE_LIKE = 'response';   // 推送类型: 回应
    const PUSH_TYPE_ATME = 'atme';
    
    /***任务类型***/
    const TASK_TYPE_ONE = 0; // 任务类型:向单个用户推送的值
    const TASK_TYPE_ALL = -1; // 任务类型:向所有用户推送的值

    /***客户端类型***/
    const CLIENT_KEY_YOUHE = '2eea4d2ff6cf5d6e962d4f9835939cf3'; // 明文: #yoho!友和#
    
    /**
     * 存放推送类型及内容模板
     * 
     * @var array
     */
    private static $_notices = array('comment' => '%s评论了你:%s', 'follow' => '%s已开始关注你%s', 'response' => '%s回应了你的照片%s', 'system' => '系统消息:%s%s', 'atme' => '%s对你说:%s');
    
    /**
     * 向单个客户端用户推送消息
     * 
     * @param integer $pushUid (推送的用户UID, 默认为null)
     * @param integer $pushedUid (被推送的用户UID)
     * @param string $pushType (推送的类型)
     * @param string $pushCustomKey (推送的客户端标识)
     * @return boolean (false:失败, true:成功)
     */
    public static function pushOne($pushUid, $pushedUid, $pushType = null, $pushContent = null, $pushCustomKey = self::CLIENT_KEY_YOUHE)
    {
        $result = false;
        
        if (USE_PUSH && is_numeric($pushedUid) && $pushedUid != $pushUid && $pushType !== null && $pushContent !== null && $pushCustomKey !== null)
        {
            // 获取推送者名称 (返回string格式)
            $pushName = is_numeric($pushUid) ? Facade_Passport_Userinfo::getNicknameByUid($pushUid) : '';
            // 生成推送的内容 (返回json格式: {"t":"类型","c":"内容"})
            $pushContent = self::genContent($pushType, $pushName, $pushContent, $pushedUid);
            // 生成推送的任务 (返回array格式)
            $pushTask = self::makeTask($pushCustomKey, $pushedUid, self::TASK_TYPE_ONE, $pushContent);
            // 添加推送的任务 (返回bool格式: false:失败, true:成功)
            $result = self::addTask($pushedUid, $pushType, $pushTask);
        }
        
        return $result;
    }
    
    /**
     * 向多个客户端用户推送消息
     * 
     * @param integer $pushUid (推送的用户UID, 默认为null)
     * @param array $pushedUids (被推送的用户UIDS)
     * @param string $pushType (推送的类型)'
     * @param string $pushCustomKey (推送的客户端标识)
     * @return boolean (false:失败, true:成功)
     */
    public static function pushMulti($pushUid, $pushedUids, $pushType = null, $pushContent = null, $pushCustomKey = self::CLIENT_KEY_YOUHE)
    {
        $result = false;
        
        if (USE_PUSH && is_array($pushedUids) && $pushType !== null && $pushContent !== null && $pushCustomKey !== null)
        {
            $pushTask = array();
            // 获取推送者名称 (返回string格式)
            $pushName = is_numeric($pushUid) ? Facade_Passport_Userinfo::getNicknameByUid($pushUid) : '';
            
            $thisPushContent = '';
            
            foreach ($pushedUids as $pushedUid)
            {
                // 生成推送的内容 (返回json格式: {"t":"类型","c":"内容"})
                $thisPushContent = self::genContent($pushType, $pushName, $pushContent, $pushedUid);
                // 生成推送的任务 (返回array格式)
                $pushTask = self::makeTask($pushCustomKey, $pushedUid, self::TASK_TYPE_ONE, $thisPushContent);
                // 添加推送的任务 (返回bool格式: false:失败, true:成功)
                $result = self::addTask($pushedUid, $pushType, $pushTask);
            }
        }
        
        return $result;
    }
    
    /**
     * 向所有客户端设备推送消息
     * 
     * @param integer $pushUid (推送的用户UID, 默认为null)
     * @param array $pushedUid (被推送的用户UID)
     * @param string $pushType (推送的类型)'
     * @param string $pushCustomKey (推送的客户端标识)
     * 
     * @return boolean (false:失败, true:成功)
     */
    public static function pushAll($pushUid, $pushedUid = -1, $pushType = null, $pushContent = null, $pushCustomKey = self::CLIENT_KEY_YOUHE)
    {
        $result = false;
        
        if (USE_PUSH && is_numeric($pushedUid) && $pushType !== null && $pushContent !== null && $pushCustomKey !== null)
        {
            // 获取推送者名称 (返回string格式)
            $pushName = is_numeric($pushUid) ? Facade_Passport_Userinfo::getNicknameByUid($pushUid) : '';
            // 生成推送的内容 (返回json格式: {"t":"类型","c":"内容"})
            $pushContent = self::genContent($pushType, $pushName, $pushContent, null);
        	// 生成推送的任务 (返回array格式)
        	$pushTask = self::makeTask($pushCustomKey, $pushedUid, self::TASK_TYPE_ALL, $pushContent);
        	// 添加推送的任务 (返回 false:失败, true:成功)
        	$result = Facade_Mobile_Pushtask::setPushTask($pushTask);
        }
        
        return $result;
    }
    
    /**
     * 检查是否需要推送
     *
     * @param string $settings (推送的设置)
     * @param string $type (推送的类型)
     * @return boolean (false:否, true:是)
     */
    public static function isPush($settings, $type)
    {
        $result = false;
        
        // 判断此用户是否接收此推送项的通知
        if (is_array($settings) && !empty($settings[$type]))
        {
        	$start = intval($settings['start'], 10);
        	$time = date('G', time());
        	$end = intval($settings['end'], 10);
        	 
        	// 检查当前时间是否在推送的时间段内
        	if (($start <= $time && $time < $end) || ($start > $end && (($start <= $time && $time < 24) || (0 <= $time && $time < $end))))
        	{
        		$result = true;
        	}
        }
        
    	return $result;
    }
    
    /**
     * 添加推送任务
     * 
     * @param integer $uid (用户UID)
     * @param string $type (任务类型, 0:向单个用户发送, 1:向全部客户端发送, 2:根据规则向部分用户发送)
     * @param array $task (推送的任务)
     * @return boolean (false:失败, true:成功)
     */
    public static function addTask($uid, $type, $task)
    {
        $result = false;
        
        if (is_numeric($uid) && isset($type) && is_array($task))
        {
            try
            {
                // 获取此用户在手机客户端的推送设置, 返回数组类型格式
                $settings = Facade_Mobile_Pushsetting::getPushNotice($uid);
                // 判断此用户是否接收此推送项的通知, 如果接收则向推送任务队列添加一推送任务
                if ($settings === array() || self::isPush($settings, $type))
                {
                    $result = Facade_Mobile_Pushtask::setPushTask($task);
                }
            }
            catch (Exception $e)
            {
                $result = false;
            }
        }
        
        return $result;
    }
    
    /**
     * 生成推送任务
     * 
     * @param string $pushCustomKey (推送的客户端标识)
     * @param integer $pushedUid (被推送的用户UID)
     * @param string $pushType (推送任务的类型 , 0:向单个用户发送, 1:向全部客户端发送, 2:根据规则向部分用户发送)
     * @param string $pushContent (推送的内容)
     * @param integer $taskRule (推送的规则 如果task_type为2, 则使用此任务规则, 制定向哪些用户发送的规则)
     * @param string $schedule (推送的计划任务)
     * @param integer $status (执行状态, 0: 未执行, 1:执行正确, 2:执行错误, 3:执行中)
     * @return array
     */
    protected static function makeTask($pushCustomKey, $pushedUid, $pushType, $pushContent, $taskRule = null, $schedule = '', $status = 0)
    {
        $task = array(
            'custom_key' => $pushCustomKey, 'task_content' => $pushContent, 'task_type' => $pushType,
            'task_rule' => $taskRule, 'user_id' => $pushedUid, 'schedule' => $schedule,
            'status' => $status, 'create_time' => time(),
        );
    	return $task;
    }
    
    /**
     * 获取推送内容
     * 
     * @param string $pushtype (推送的类型)
     * @param string $pushname (推送者名称)
     * @param string $pushContent (推送的内容)
     * @return json
     * @example {"t":"类型", "c":"内容"}
     */
    protected static function genContent($pushType, $pushName, $pushContent, $pushedUid)
    {
        if (isset(self::$_notices[$pushType]))
        {
            $pushContent = sprintf(self::$_notices[$pushType], $pushName, $pushContent);
        }
        
        $messageNum = is_numeric($pushedUid) ? Facade_Message_Notice::getUnreadNoticeNum($pushedUid) : null;
        $messageNum = empty($messageNum) ? 1 : intval($messageNum, 10);
        
        // t: 类型, c: 内容, num: 提醒的未读数, g: 自定义的参数值
        $formatContent = Util_Json::encode(array('t' => $pushType, 'c' => Util_StringHelper::substr_filter($pushContent, 50), 'num' => $messageNum,));
        
        return $formatContent;
    }

}