<?php
//  ---------------------------------------------------------------------------------
//    _____   _             _                   _   _____
//   |  __ \ | |           | |    /\           (_) |  __ \
//   | |__) || |__    __ _ | |   /  \    _ __   _  | |__) |_ __  ___
//   |  ___/ | '_ \  / _` || |  / /\ \  | '_ \ | | |  ___/| '__|/ _ \
//   | |     | | | || (_| || | / ____ \ | |_) || | | |    | |  | (_) |
//   |_|     |_| |_| \__,_||_|/_/    \_\| .__/ |_| |_|    |_|   \___/
//                                      | |
//                                      |_|
//   PhalApi Pro 专业版
//   广州果创网络科技有限公司
//
//  ---------------------------------------------------------------------------------
//
//   一、协议的许可和权利
//    1. 您可以在完全遵守本协议的基础上，将本软件应用于商业用途；
//    2. 您可以在协议规定的约束和限制范围内修改本产品源代码或界面风格以适应您的要求；
//    3. 您拥有使用本产品中的全部内容资料、商品信息及其他信息的所有权，并独立承担与其内容相关的
//       法律义务；
//    4. 获得商业授权之后，您可以将本软件应用于商业用途，自授权时刻起，在技术支持期限内拥有通过
//       指定的方式获得指定范围内的技术支持服务；
//
//   二、协议的约束和限制
//    1. 未获商业授权之前，禁止将本软件用于商业用途（包括但不限于企业法人经营的产品、经营性产品
//       以及以盈利为目的或实现盈利产品）；
//    2. 未获商业授权之前，禁止在本产品的整体或在任何部分基础上发展任何派生版本、修改版本或第三
//       方版本用于重新开发；
//    3. 如果您未能遵守本协议的条款，您的授权将被终止，所被许可的权利将被收回并承担相应法律责任；
//
//   三、有限担保和免责声明
//    1. 本软件及所附带的文件是作为不提供任何明确的或隐含的赔偿或担保的形式提供的；
//    2. 用户出于自愿而使用本软件，您必须了解使用本软件的风险，在尚未获得商业授权之前，我们不承
//       诺提供任何形式的技术支持、使用担保，也不承担任何因使用本软件而产生问题的相关责任；
//    3. 广州果创网络科技有限公司不对使用本产品构建的商城中的内容信息承担责任，但在不侵犯用户隐
//       私信息的前提下，保留以任何方式获取用户信息及商品信息的权利；
//
//   有关本产品最终用户授权协议、商业授权与技术服务的详细内容，均由广州果创网络科技有限公司独家
//   提供。广州果创网络科技有限公司拥有在不事先通知的情况下，修改授权协议的权力，修改后的协议对
//   改变之日起的新授权用户生效。电子文本形式的授权协议如同双方书面签署的协议一样，具有完全的和
//   等同的法律效力。您一旦开始修改、安装或使用本产品，即被视为完全理解并接受本协议的各项条款，
//   在享有上述条款授予的权力的同时，受到相关的约束和限制。协议许可范围以外的行为，将直接违反本
//   授权协议并构成侵权，我们有权随时终止授权，责令停止损害，并保留追究相关责任的权力。
//
//  ---------------------------------------------------------------------------------

namespace App\Common;
use PhalApi\Exception\BadRequestException;
use Base\Domain\Rights as RightsDomain;

/**
 * 前台接口基类
 * @exception 400 ret=400，客户端参数错误或非法请求
 * @exception 406 ret=406，access_token令牌校验不通过
 * @exception 407 ret=407，app_key权限不足，或未知应用
 * @exception 408 ret=408，当前用户禁止使用，或用户未登录
 */
class Api extends \PhalApi\Api {

	/**
	 * 尝试获取本次已登录的用户ID
	 * @param  boolean $isStopWhenNotLogin 当用户未登录时是否抛出异常，中止接口请求
	 * @return int 登录的用户ID，若未登录且未抛出异常则返回0
	 */
	protected function tryToGetUid($isStopWhenNotLogin = true) {
	    $uid = $this->getCurContext()->getUid();
		if ($uid <= 0 && $isStopWhenNotLogin) {
			throw new BadRequestException(\PhalApi\T("user not login"), 8);
		}
		return $uid;
	}

	/**
	 * 检测用户是否已登录
	 * @throw PhalApi\Exception\BadRequestException
	 */
	protected function checkUserLogin() {
	    $uid = $this->getCurContext()->getUid();
		if ($uid <= 0) {
			throw new BadRequestException(\PhalApi\T("user not login"), 8);
		}
	}
	
	/**
	 * 尝试获取app_key
	 * @param boolean $isStopWhenNoApp 未指定应用时，是否抛出异常并中止接口请求
	 * @throws BadRequestException
	 * @return string 当前app_key，若未指定且未抛出异常则返回默认的空应用（即空字符串）
	 */
	protected function tryToGetAppKey($isStopWhenNoApp = true) {
	    $appKey = $this->getCurContext()->getAppKey();
	    if (empty($appKey) && $isStopWhenNoApp) {
	        throw new BadRequestException(\PhalApi\T("unknown application"), 7);
	    }
	    return $appKey;
	}
	
    /**
     * 检测当前应用
     * @throws BadRequestException
     */	
	protected function checkAppOnline($isStopWhenNoApp = true) {
	    $appKey = $this->getCurContext()->getAppKey();
	    if (empty($appKey) && $isStopWhenNoApp) {
	        throw new BadRequestException(\PhalApi\T("unknown application"), 7);
	    }
	}
	
	/**
	 * 获取上下文信息
	 * @return Base\Common\Context
	 */
	protected function getCurContext() {
	    return \PhalApi\DI()->context;
	}
	
	/**
	 * 进行接口权限判断
	 * @throws BadRequestException
	 */
	protected function userCheck() {
	    $di = \PhalApi\DI();
	    $appKey = $di->context->getAppKey();
	    $service = $di->request->getService();
	    
	    // 白名单
	    $whitelist = $this->userCheckActionWhitelist();
	    if (is_array($whitelist) && !empty($whitelist)) {
	        $actionName = $di->request->getServiceAction();
	        $actionName = strtolower($actionName);
	        foreach ($whitelist as $val) {
	            if (strtolower($val) == $actionName) {
	                return;
	            }
	        }
	    }
	    
	    // 缺少app_key，无法检测。可能场景：配置了接口白名单。
	    if (empty($appKey)) {
	        return;
	    }
	    
	    $domain = new RightsDomain();
	    if (!$domain->checkAppRights($appKey, $service)) {
	        throw new BadRequestException(\PhalApi\T("api inadequate permissions"), 7);
	    }
	}
	
	/**
	 * 接口权限检测的白名单，返回当前API接口类的方法名即可，例如：return array('userLogin');
	 */
	protected function userCheckActionWhitelist() {
	    return array();
	}
}
