代码初始化
This commit is contained in:
146
extend/AliPayV2/AliPay.php
Normal file
146
extend/AliPayV2/AliPay.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
use think\Loader;
|
||||
|
||||
/**
|
||||
* 支付宝插件 使用方法请查看同文件夹下的demo
|
||||
* 目前已经支持电脑网站支付,手机APP支付,支付回调校验,用户提现等功能,如需拓展请联系作者
|
||||
* @author Jack_YanTC <627495692@qq.com>
|
||||
*/
|
||||
class AliPay
|
||||
{
|
||||
private $appId;
|
||||
private $rsaPrivateKey;
|
||||
private $notifyUrl;
|
||||
private $alipayPublicKey;
|
||||
private $appCertPath;
|
||||
private $alipayCertPath;
|
||||
private $rootCertPath;
|
||||
|
||||
/**
|
||||
* 初始化参数
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->appCertPath = ADDON_PATH . 'epay/certs/appCertPublicKey_2021005162648430.crt';
|
||||
$this->alipayCertPath = ADDON_PATH . 'epay/certs/alipayCertPublicKey_RSA2.crt';
|
||||
$this->rootCertPath = ADDON_PATH . 'epay/certs/alipayRootCert.crt';
|
||||
|
||||
$configs = get_system_config();
|
||||
$this->appId = $configs['alipay_app_id'];
|
||||
$this->rsaPrivateKey = $configs['alipay_private_key'];
|
||||
$this->alipayPublicKey = $configs['alipay_public_key'];
|
||||
$this->notifyUrl = $configs['web_site']."/api/Payment/notify_ali";
|
||||
|
||||
$aliPayPath = EXTEND_PATH.'/AliPayV2/alipay-sdk/aopV2/';
|
||||
require_once $aliPayPath . 'AopCertClient.php';
|
||||
require_once $aliPayPath . 'AopClient.php';
|
||||
require_once $aliPayPath . 'AopCertification.php';
|
||||
require_once $aliPayPath . 'AlipayConfig.php';
|
||||
require_once $aliPayPath . 'request/AlipaySystemOauthTokenRequest.php';
|
||||
require_once $aliPayPath . 'request/AlipayUserInfoShareRequest.php';
|
||||
require_once $aliPayPath . 'request/AlipayTradeAppPayRequest.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝手机网站支付
|
||||
* @param string $orderid 订单号
|
||||
* @param string $money 金额
|
||||
* @param string $subject 标题
|
||||
* @return string
|
||||
*/
|
||||
public function aliAppPays($orderid, $money, $subject)
|
||||
{
|
||||
$aop = new AopCertClient ();
|
||||
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
|
||||
$aop->appId = $this->appId;
|
||||
$aop->rsaPrivateKey = $this->rsaPrivateKey;
|
||||
$aop->alipayrsaPublicKey = $aop->getPublicKey($this->alipayCertPath);//调用getPublicKey从支付宝公钥证书中提取公钥
|
||||
$aop->apiVersion = '1.0';
|
||||
$aop->signType = 'RSA2';
|
||||
$aop->postCharset = 'utf-8';
|
||||
$aop->format = 'json';
|
||||
$aop->isCheckAlipayPublicCert = true;//是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内
|
||||
$aop->appCertSN = $aop->getCertSN($this->appCertPath);//调用getCertSN获取证书序列号
|
||||
$aop->alipayRootCertSN = $aop->getRootCertSN($this->rootCertPath);//调用getRootCertSN获取支付宝根证书序列号
|
||||
|
||||
$request = new AlipayTradeAppPayRequest ();
|
||||
|
||||
$bizcontent = json_encode([
|
||||
'subject' => $subject,
|
||||
'out_trade_no' => $orderid,//此订单号为商户唯一订单号
|
||||
'total_amount' => $money//保留两位小数
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
$request->setNotifyUrl($this->notifyUrl);
|
||||
$request->setBizContent($bizcontent);
|
||||
|
||||
$result = $aop->sdkExecute($request);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function verify($post)
|
||||
{
|
||||
$aop = new AopCertClient ();
|
||||
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
|
||||
$aop->appId = $this->appId;
|
||||
$aop->rsaPrivateKey = $this->rsaPrivateKey;
|
||||
$aop->alipayrsaPublicKey = $aop->getPublicKey($this->alipayCertPath);//调用getPublicKey从支付宝公钥证书中提取公钥
|
||||
$aop->apiVersion = '1.0';
|
||||
$aop->signType = 'RSA2';
|
||||
$aop->postCharset = 'utf-8';
|
||||
$aop->format = 'json';
|
||||
$aop->isCheckAlipayPublicCert = true;//是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内
|
||||
$aop->appCertSN = $aop->getCertSN($this->appCertPath);//调用getCertSN获取证书序列号
|
||||
$aop->alipayRootCertSN = $aop->getRootCertSN($this->rootCertPath);//调用getRootCertSN获取支付宝根证书序列号
|
||||
|
||||
return $aop->rsaCheckV1($post, NULL, "RSA2");
|
||||
}
|
||||
|
||||
|
||||
//支付宝换取访问令牌
|
||||
public function login($auth_code)
|
||||
{
|
||||
$aop = new AopCertClient ();
|
||||
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
|
||||
$aop->appId = $this->appId;
|
||||
$aop->rsaPrivateKey = $this->rsaPrivateKey;
|
||||
$aop->alipayrsaPublicKey = $aop->getPublicKey($this->alipayCertPath);//调用getPublicKey从支付宝公钥证书中提取公钥
|
||||
$aop->apiVersion = '1.0';
|
||||
$aop->signType = 'RSA2';
|
||||
$aop->postCharset = 'utf-8';
|
||||
$aop->format = 'json';
|
||||
$aop->isCheckAlipayPublicCert = true;//是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内
|
||||
$aop->appCertSN = $aop->getCertSN($this->appCertPath);//调用getCertSN获取证书序列号
|
||||
$aop->alipayRootCertSN = $aop->getRootCertSN($this->rootCertPath);//调用getRootCertSN获取支付宝根证书序列号
|
||||
|
||||
|
||||
// 创建请求对象
|
||||
$request = new AlipaySystemOauthTokenRequest();//AlipaySystemOauthTokenRequest
|
||||
$request->setGrantType("authorization_code");
|
||||
$request->setCode( $auth_code);
|
||||
|
||||
// 执行请求,获取access_token
|
||||
$result = $aop->execute($request);
|
||||
|
||||
if (isset( $result->alipay_system_oauth_token_response->access_token)) {
|
||||
// 获取用户信息
|
||||
$userinfo_request = new AlipayUserInfoShareRequest();
|
||||
$userinfo_result = $aop->execute( $userinfo_request, $result->alipay_system_oauth_token_response->access_token);
|
||||
if ($userinfo_result->alipay_user_info_share_response->code == '10000') {
|
||||
// 处理用户信息,例如保存到数据库
|
||||
$user_info = $userinfo_result->alipay_user_info_share_response;
|
||||
return ['code'=>'1','msg'=>'success','data'=>$user_info];
|
||||
} else {
|
||||
// 处理错误
|
||||
return ['code'=>$result->error_response->code,'msg'=>$result->error_response->msg.'/'.$result->error_response->sub_code,'data'=>$result->error_response->sub_msg];
|
||||
}
|
||||
} else {
|
||||
// 处理错误
|
||||
return ['code'=>$result->error_response->code,'msg'=>$result->error_response->msg.'/'.$result->error_response->sub_code,'data'=>$result->error_response->sub_msg];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
197
extend/AliPayV2/alipay-sdk/aopV2/AlipayConfig.php
Normal file
197
extend/AliPayV2/alipay-sdk/aopV2/AlipayConfig.php
Normal file
@@ -0,0 +1,197 @@
|
||||
|
||||
<?php
|
||||
class AlipayConfig {
|
||||
/**
|
||||
* 网关地址
|
||||
* 线上:https://openapi.alipay.com/gateway.do
|
||||
* 沙箱:https://openapi.alipaydev.com/gateway.do
|
||||
*/
|
||||
private $serverUrl;
|
||||
|
||||
/**
|
||||
* 开放平台上创建的应用的ID
|
||||
*/
|
||||
private $appId;
|
||||
|
||||
/**
|
||||
* 报文格式,推荐:json
|
||||
*/
|
||||
private $format = "json";
|
||||
|
||||
/**
|
||||
* 字符串编码,推荐:utf-8
|
||||
*/
|
||||
private $charset = "utf-8";
|
||||
|
||||
/**
|
||||
* 签名算法类型,推荐:RSA2
|
||||
*/
|
||||
private $signType = "RSA2";
|
||||
|
||||
/**
|
||||
* 商户私钥
|
||||
*/
|
||||
private $privateKey;
|
||||
|
||||
/**
|
||||
* 支付宝公钥字符串(公钥模式下设置,证书模式下无需设置)
|
||||
*/
|
||||
private $alipayPublicKey;
|
||||
|
||||
/**
|
||||
* 商户应用公钥证书路径(证书模式下设置,公钥模式下无需设置)
|
||||
*/
|
||||
private $appCertPath;
|
||||
|
||||
/**
|
||||
* 支付宝公钥证书路径(证书模式下设置,公钥模式下无需设置)
|
||||
*/
|
||||
private $alipayPublicCertPath;
|
||||
|
||||
/**
|
||||
* 支付宝根证书路径(证书模式下设置,公钥模式下无需设置)
|
||||
*/
|
||||
private $rootCertPath;
|
||||
|
||||
/**
|
||||
* 指定商户公钥应用证书内容字符串,该字段与appCertPath只需指定一个,优先以该字段的值为准(证书模式下设置,公钥模式下无需设置)
|
||||
*/
|
||||
private $appCertContent;
|
||||
|
||||
/**
|
||||
* 指定支付宝公钥证书内容字符串,该字段与alipayPublicCertPath只需指定一个,优先以该字段的值为准(证书模式下设置,公钥模式下无需设置)
|
||||
*/
|
||||
private $alipayPublicCertContent;
|
||||
|
||||
/**
|
||||
* 指定根证书内容字符串,该字段与rootCertPath只需指定一个,优先以该字段的值为准(证书模式下设置,公钥模式下无需设置)
|
||||
*/
|
||||
private $rootCertContent;
|
||||
|
||||
/**
|
||||
* 敏感信息对称加密算法类型,推荐:AES
|
||||
*/
|
||||
private $encryptType = "AES";
|
||||
|
||||
/**
|
||||
* 敏感信息对称加密算法密钥
|
||||
*/
|
||||
private $encryptKey;
|
||||
|
||||
/**
|
||||
* 跳过加验签(小程序云免鉴权)
|
||||
*/
|
||||
private $skipSign = false;
|
||||
|
||||
|
||||
public function getServerUrl() {
|
||||
return $this->serverUrl;
|
||||
}
|
||||
|
||||
public function setServerUrl($serverUrl) {
|
||||
$this->serverUrl = $serverUrl;
|
||||
}
|
||||
public function getAppId(){
|
||||
return $this->appId;
|
||||
}
|
||||
public function setAppId($appId){
|
||||
$this->appId = $appId;
|
||||
}
|
||||
public function getFormat(){
|
||||
return $this->format;
|
||||
}
|
||||
public function setFormat($format){
|
||||
$this->format = $format;
|
||||
}
|
||||
public function getCharset() {
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
public function setCharset($charset) {
|
||||
$this->charset = $charset;
|
||||
}
|
||||
|
||||
public function getSignType() {
|
||||
return $this->signType;
|
||||
}
|
||||
|
||||
public function setSignType($signType) {
|
||||
$this->signType = $signType;
|
||||
}
|
||||
public function getEncryptKey() {
|
||||
return $this->encryptKey;
|
||||
}
|
||||
|
||||
public function setEncryptKey($encryptKey) {
|
||||
$this->encryptKey = $encryptKey;
|
||||
}
|
||||
public function getEncryptType() {
|
||||
return $this->encryptType;
|
||||
}
|
||||
public function setEncryptType($encryptType) {
|
||||
$this->encryptType = $encryptType;
|
||||
}
|
||||
public function getPrivateKey() {
|
||||
return $this->privateKey;
|
||||
}
|
||||
|
||||
public function setPrivateKey($privateKey) {
|
||||
$this->privateKey = $privateKey;
|
||||
}
|
||||
public function getAlipayPublicKey() {
|
||||
return $this->alipayPublicKey;
|
||||
}
|
||||
public function setAlipayPublicKey($alipayPublicKey) {
|
||||
$this->alipayPublicKey = $alipayPublicKey;
|
||||
}
|
||||
public function getAppCertPath() {
|
||||
return $this->appCertPath;
|
||||
}
|
||||
|
||||
public function setAppCertPath($appCertPath) {
|
||||
$this->appCertPath = $appCertPath;
|
||||
}
|
||||
|
||||
public function getAlipayPublicCertPath() {
|
||||
return $this->alipayPublicCertPath;
|
||||
}
|
||||
public function setAlipayPublicCertPath($alipayPublicCertPath) {
|
||||
$this->alipayPublicCertPath = $alipayPublicCertPath;
|
||||
}
|
||||
|
||||
public function getRootCertPath() {
|
||||
return $this->rootCertPath;
|
||||
}
|
||||
public function setRootCertPath($rootCertPath) {
|
||||
$this->rootCertPath = $rootCertPath;
|
||||
}
|
||||
public function getAppCertContent() {
|
||||
return $this->appCertContent;
|
||||
}
|
||||
public function setAppCertContent($appCertContent) {
|
||||
$this->appCertContent = $appCertContent;
|
||||
}
|
||||
public function getAlipayPublicCertContent() {
|
||||
return $this->alipayPublicCertContent;
|
||||
}
|
||||
public function setAlipayPublicCertContent($alipayPublicCertContent) {
|
||||
$this->alipayPublicCertContent = $alipayPublicCertContent;
|
||||
}
|
||||
public function getRootCertContent() {
|
||||
return $this->rootCertContent;
|
||||
}
|
||||
|
||||
public function setRootCertContent($rootCertContent) {
|
||||
$this->rootCertContent = $rootCertContent;
|
||||
}
|
||||
|
||||
public function isSkipSign()
|
||||
{
|
||||
return $this->skipSign;
|
||||
}
|
||||
|
||||
public function setSkipSign(bool $skipSign)
|
||||
{
|
||||
$this->skipSign = $skipSign;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 多媒体文件客户端
|
||||
* @author yikai.hu
|
||||
* @version $Id: AlipayMobilePublicMultiMediaClient.php, v 0.1 Aug 15, 2014 10:19:01 AM yikai.hu Exp $
|
||||
*/
|
||||
|
||||
include("AlipayMobilePublicMultiMediaExecute.php");
|
||||
|
||||
class AlipayMobilePublicMultiMediaClient
|
||||
{
|
||||
private $DEFAULT_CHARSET = 'UTF-8';
|
||||
private $METHOD_POST = "POST";
|
||||
private $METHOD_GET = "GET";
|
||||
private $SIGN = 'sign'; //get name
|
||||
|
||||
private $timeout = 10;// 超时时间
|
||||
private $serverUrl;
|
||||
private $appId;
|
||||
private $privateKey;
|
||||
private $prodCode;
|
||||
private $format = 'json'; //todo
|
||||
private $sign_type = 'RSA'; //todo
|
||||
|
||||
private $charset;
|
||||
private $apiVersion = "1.0";
|
||||
private $apiMethodName = "alipay.mobile.public.multimedia.download";
|
||||
private $media_id = "L21pZnMvVDFQV3hYWGJKWFhYYUNucHJYP3Q9YW13ZiZ4c2lnPTU0MzRhYjg1ZTZjNWJmZTMxZGJiNjIzNDdjMzFkNzkw575";
|
||||
//此处写死的,实际开发中,请传入
|
||||
|
||||
private $connectTimeout = 3000;
|
||||
private $readTimeout = 15000;
|
||||
|
||||
function __construct($serverUrl = '', $appId = '', $partner_private_key = '', $format = '', $charset = 'GBK')
|
||||
{
|
||||
$this->serverUrl = $serverUrl;
|
||||
$this->appId = $appId;
|
||||
$this->privateKey = $partner_private_key;
|
||||
$this->format = $format;
|
||||
$this->charset = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* getContents 获取网址内容
|
||||
* @param $request
|
||||
* @return text | bin
|
||||
*/
|
||||
public function getContents()
|
||||
{
|
||||
$datas = array(
|
||||
"app_id" => $this->appId,
|
||||
"method" => $this->METHOD_POST,
|
||||
"sign_type" => $this->sign_type,
|
||||
"version" => $this->apiVersion,
|
||||
"timestamp" => date('Y-m-d H:i:s'),//yyyy-MM-dd HH:mm:ss
|
||||
"biz_content" => '{"mediaId":"' . $this->media_id . '"}',
|
||||
"charset" => $this->charset
|
||||
);
|
||||
|
||||
//要提交的数据
|
||||
$data_sign = $this->buildGetUrl($datas);
|
||||
|
||||
$post_data = $data_sign;
|
||||
//初始化 curl
|
||||
$ch = curl_init();
|
||||
//设置目标服务器
|
||||
curl_setopt($ch, CURLOPT_URL, $this->serverUrl);
|
||||
curl_setopt($ch, CURLOPT_HEADER, TRUE);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
//超时时间
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
|
||||
|
||||
if ($this->METHOD_POST == 'POST') {
|
||||
// post数据
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
// post的变量
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
|
||||
}
|
||||
|
||||
|
||||
$output = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
echo $output;
|
||||
|
||||
$datas = explode("\r\n\r\n", $output, 2);
|
||||
$header = $datas[0];
|
||||
|
||||
if ($httpCode == '200') {
|
||||
$body = $datas[1];
|
||||
} else {
|
||||
$body = '';
|
||||
|
||||
}
|
||||
|
||||
return $this->execute($header, $body, $httpCode);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param $request
|
||||
* @return text | bin
|
||||
*/
|
||||
public function execute($header = '', $body = '', $httpCode = '')
|
||||
{
|
||||
$exe = new AlipayMobilePublicMultiMediaExecute($header, $body, $httpCode);
|
||||
return $exe;
|
||||
}
|
||||
|
||||
public function buildGetUrl($query = array())
|
||||
{
|
||||
if (!is_array($query)) {
|
||||
//exit;
|
||||
}
|
||||
//排序参数,
|
||||
$data = $this->buildQuery($query);
|
||||
|
||||
// 私钥密码
|
||||
$passphrase = '';
|
||||
$key_width = 64;
|
||||
|
||||
//私钥
|
||||
$privateKey = $this->privateKey;
|
||||
$p_key = array();
|
||||
//如果私钥是 1行
|
||||
if (!stripos($privateKey, "\n")) {
|
||||
$i = 0;
|
||||
while ($key_str = substr($privateKey, $i * $key_width, $key_width)) {
|
||||
$p_key[] = $key_str;
|
||||
$i++;
|
||||
}
|
||||
} else {
|
||||
//echo '一行?';
|
||||
}
|
||||
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . implode("\n", $p_key);
|
||||
$privateKey = $privateKey . "\n-----END RSA PRIVATE KEY-----";
|
||||
|
||||
//私钥
|
||||
$private_id = openssl_pkey_get_private($privateKey, $passphrase);
|
||||
|
||||
// 签名
|
||||
$signature = '';
|
||||
|
||||
if ("RSA2" == $this->sign_type) {
|
||||
|
||||
openssl_sign($data, $signature, $private_id, OPENSSL_ALGO_SHA256);
|
||||
} else {
|
||||
|
||||
openssl_sign($data, $signature, $private_id, OPENSSL_ALGO_SHA1);
|
||||
}
|
||||
|
||||
openssl_free_key($private_id);
|
||||
|
||||
//加密后的内容通常含有特殊字符,需要编码转换下
|
||||
$signature = base64_encode($signature);
|
||||
|
||||
$signature = urlencode($signature);
|
||||
|
||||
//$signature = 'XjUN6YM1Mc9HXebKMv7GTLy7gmyhktyOgKk2/Jf+cz4DtP6udkzTdpkjW2j/Z4ZSD7xD6CNYI1Spz4yS93HPT0a5X9LgFWYY8SaADqe+ArXg+FBSiTwUz49SE//Xd9+LEiIRsSFkbpkuiGoO6mqJmB7vXjlD5lx6qCM3nb41wb8=';
|
||||
|
||||
$out = $data . '&' . $this->SIGN . '=' . $signature;
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/*
|
||||
* 查询参数排序 a-z
|
||||
* */
|
||||
public function buildQuery($query)
|
||||
{
|
||||
if (!$query) {
|
||||
return null;
|
||||
}
|
||||
//将要 参数 排序
|
||||
ksort($query);
|
||||
|
||||
//重新组装参数
|
||||
$params = array();
|
||||
foreach ($query as $key => $value) {
|
||||
$params[] = $key . '=' . $value;
|
||||
}
|
||||
$data = implode('&', $params);
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 多媒体文件客户端
|
||||
* @author yuanwai.wang
|
||||
* @version $Id: AlipayMobilePublicMultiMediaExecute.php, v 0.1 Aug 15, 2014 10:19:01 AM yuanwai.wang Exp $
|
||||
*/
|
||||
|
||||
//namespace alipay\api ;
|
||||
|
||||
|
||||
class AlipayMobilePublicMultiMediaExecute
|
||||
{
|
||||
|
||||
private $code = 200;
|
||||
private $msg = '';
|
||||
private $body = '';
|
||||
private $params = '';
|
||||
|
||||
private $fileSuffix = array(
|
||||
"image/jpeg" => 'jpg', //+
|
||||
"text/plain" => 'text'
|
||||
);
|
||||
|
||||
/*
|
||||
* @$header : 头部
|
||||
* */
|
||||
function __construct($header, $body, $httpCode)
|
||||
{
|
||||
$this->code = $httpCode;
|
||||
$this->msg = '';
|
||||
$this->params = $header;
|
||||
$this->body = $body;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return text | bin
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return text | bin
|
||||
*/
|
||||
public function getMsg()
|
||||
{
|
||||
return $this->msg;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return text | bin
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
$subject = $this->params;
|
||||
$pattern = '/Content\-Type:([^;]+)/';
|
||||
preg_match($pattern, $subject, $matches);
|
||||
if ($matches) {
|
||||
$type = $matches[1];
|
||||
} else {
|
||||
$type = 'application/download';
|
||||
}
|
||||
|
||||
return str_replace(' ', '', $type);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return text | bin
|
||||
*/
|
||||
public function getContentLength()
|
||||
{
|
||||
$subject = $this->params;
|
||||
$pattern = '/Content-Length:\s*([^\n]+)/';
|
||||
preg_match($pattern, $subject, $matches);
|
||||
return (int)(isset($matches[1]) ? $matches[1] : '');
|
||||
}
|
||||
|
||||
|
||||
public function getFileSuffix($fileType)
|
||||
{
|
||||
$type = isset($this->fileSuffix[$fileType]) ? $this->fileSuffix[$fileType] : 'text/plain';
|
||||
if (!$type) {
|
||||
$type = 'json';
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return text | bin
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
//header('Content-type: image/jpeg');
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数
|
||||
* @return text | bin
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
1303
extend/AliPayV2/alipay-sdk/aopV2/AopCertClient.php
Normal file
1303
extend/AliPayV2/alipay-sdk/aopV2/AopCertClient.php
Normal file
File diff suppressed because it is too large
Load Diff
527
extend/AliPayV2/alipay-sdk/aopV2/AopCertification.php
Normal file
527
extend/AliPayV2/alipay-sdk/aopV2/AopCertification.php
Normal file
@@ -0,0 +1,527 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 验证支付宝公钥证书是否可信
|
||||
* @param $alipayCert 支付宝公钥证书
|
||||
* @param $rootCert 支付宝根证书
|
||||
*/
|
||||
function isTrusted($alipayCert, $rootCert)
|
||||
{
|
||||
$alipayCerts = readPemCertChain($alipayCert);
|
||||
$rootCerts = readPemCertChain($rootCert);
|
||||
if (verifyCertChain($alipayCerts, $rootCerts)) {
|
||||
return verifySignature($alipayCert, $rootCert);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function verifySignature($alipayCert, $rootCert)
|
||||
{
|
||||
$alipayCertArray = explode("-----END CERTIFICATE-----", $alipayCert);
|
||||
$rootCertArray = explode("-----END CERTIFICATE-----", $rootCert);
|
||||
$length = count($rootCertArray) - 1;
|
||||
$checkSign = isCertSigner($alipayCertArray[0] . "-----END CERTIFICATE-----", $alipayCertArray[1] . "-----END CERTIFICATE-----");
|
||||
if (!$checkSign) {
|
||||
$checkSign = isCertSigner($alipayCertArray[1] . "-----END CERTIFICATE-----", $alipayCertArray[0] . "-----END CERTIFICATE-----");
|
||||
if ($checkSign) {
|
||||
$issuer = openssl_x509_parse($alipayCertArray[0] . "-----END CERTIFICATE-----")['issuer'];
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$subject = openssl_x509_parse($rootCertArray[$i] . "-----END CERTIFICATE-----")['subject'];
|
||||
if ($issuer == $subject) {
|
||||
isCertSigner($alipayCertArray[0] . "-----END CERTIFICATE-----", $rootCertArray[$i] . $rootCertArray);
|
||||
return $checkSign;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return $checkSign;
|
||||
}
|
||||
} else {
|
||||
$issuer = openssl_x509_parse($alipayCertArray[1] . "-----END CERTIFICATE-----")['issuer'];
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$subject = openssl_x509_parse($rootCertArray[$i] . "-----END CERTIFICATE-----")['subject'];
|
||||
if ($issuer == $subject) {
|
||||
$checkSign = isCertSigner($alipayCertArray[1] . "-----END CERTIFICATE-----", $rootCertArray[$i] . "-----END CERTIFICATE-----");
|
||||
return $checkSign;
|
||||
}
|
||||
}
|
||||
return $checkSign;
|
||||
}
|
||||
}
|
||||
|
||||
function readPemCertChain($cert)
|
||||
{
|
||||
$array = explode("-----END CERTIFICATE-----", $cert);
|
||||
$certs[] = null;
|
||||
for ($i = 0; $i < count($array) - 1; $i++) {
|
||||
$certs[$i] = openssl_x509_parse($array[$i] . "-----END CERTIFICATE-----");
|
||||
}
|
||||
return $certs;
|
||||
}
|
||||
|
||||
function verifyCert($prev, $rootCerts)
|
||||
{
|
||||
$nowTime = time();
|
||||
if ($nowTime < $prev['validFrom_time_t']) {
|
||||
echo "证书未激活";
|
||||
return false;
|
||||
}
|
||||
if ($nowTime > $prev['validTo_time_t']) {
|
||||
echo "证书已经过期";
|
||||
return false;
|
||||
}
|
||||
$subjectMap = null;
|
||||
for ($i = 0; $i < count($rootCerts); $i++) {
|
||||
$subjectDN = array2string($rootCerts[$i]['subject']);
|
||||
$subjectMap[$subjectDN] = $rootCerts[$i];
|
||||
}
|
||||
$issuerDN = array2string(($prev['issuer']));
|
||||
if (!array_key_exists($issuerDN, $subjectMap)) {
|
||||
echo "证书链验证失败";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证证书链是否是信任证书库中证书签发的
|
||||
* @param $alipayCerts 目标验证证书列表
|
||||
* @param $rootCerts 可信根证书列表
|
||||
*/
|
||||
function verifyCertChain($alipayCerts, $rootCerts)
|
||||
{
|
||||
$sorted = sortByDn($alipayCerts);
|
||||
if (!$sorted) {
|
||||
echo "证书链验证失败:不是完整的证书链";
|
||||
return false;
|
||||
}
|
||||
//先验证第一个证书是不是信任库中证书签发的
|
||||
$prev = $alipayCerts[0];
|
||||
$firstOK = verifyCert($prev, $rootCerts);
|
||||
$length = count($alipayCerts);
|
||||
if (!$firstOK || $length == 1) {
|
||||
return $firstOK;
|
||||
}
|
||||
|
||||
$nowTime = time();
|
||||
//验证证书链
|
||||
for ($i = 1; $i < $length; $i++) {
|
||||
$cert = $alipayCerts[$i];
|
||||
if ($nowTime < $cert['validFrom_time_t']) {
|
||||
echo "证书未激活";
|
||||
return false;
|
||||
}
|
||||
if ($nowTime > $cert['validTo_time_t']) {
|
||||
echo "证书已经过期";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将证书链按照完整的签发顺序进行排序,排序后证书链为:[issuerA, subjectA]-[issuerA, subjectB]-[issuerB, subjectC]-[issuerC, subjectD]...
|
||||
* @param $certs 证书链
|
||||
*/
|
||||
function sortByDn(&$certs)
|
||||
{
|
||||
//是否包含自签名证书
|
||||
$hasSelfSignedCert = false;
|
||||
$subjectMap = null;
|
||||
$issuerMap = null;
|
||||
for ($i = 0; $i < count($certs); $i++) {
|
||||
if (isSelfSigned($certs[$i])) {
|
||||
if ($hasSelfSignedCert) {
|
||||
return false;
|
||||
}
|
||||
$hasSelfSignedCert = true;
|
||||
}
|
||||
$subjectDN = array2string($certs[$i]['subject']);
|
||||
$issuerDN = array2string(($certs[$i]['issuer']));
|
||||
$subjectMap[$subjectDN] = $certs[$i];
|
||||
$issuerMap[$issuerDN] = $certs[$i];
|
||||
}
|
||||
$certChain = null;
|
||||
addressingUp($subjectMap, $certChain, $certs[0]);
|
||||
addressingDown($issuerMap, $certChain, $certs[0]);
|
||||
|
||||
//说明证书链不完整
|
||||
if (count($certs) != count($certChain)) {
|
||||
return false;
|
||||
}
|
||||
//将证书链复制到原先的数据
|
||||
for ($i = 0; $i < count($certs); $i++) {
|
||||
$certs[$i] = $certChain[count($certs) - $i - 1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证证书是否是自签发的
|
||||
* @param $cert 目标证书
|
||||
*/
|
||||
function isSelfSigned($cert)
|
||||
{
|
||||
$subjectDN = array2string($cert['subject']);
|
||||
$issuerDN = array2string($cert['issuer']);
|
||||
return ($subjectDN == $issuerDN);
|
||||
}
|
||||
|
||||
|
||||
function array2string($array)
|
||||
{
|
||||
$string = [];
|
||||
if ($array && is_array($array)) {
|
||||
foreach ($array as $key => $value) {
|
||||
$string[] = $key . '=' . $value;
|
||||
}
|
||||
}
|
||||
return implode(',', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向上构造证书链
|
||||
* @param $subjectMap 主题和证书的映射
|
||||
* @param $certChain 证书链
|
||||
* @param $current 当前需要插入证书链的证书,include
|
||||
*/
|
||||
function addressingUp($subjectMap, &$certChain, $current)
|
||||
{
|
||||
$certChain[] = $current;
|
||||
if (isSelfSigned($current)) {
|
||||
return;
|
||||
}
|
||||
$issuerDN = array2string($current['issuer']);
|
||||
|
||||
if (!array_key_exists($issuerDN, $subjectMap)) {
|
||||
return;
|
||||
}
|
||||
addressingUp($subjectMap, $certChain, $subjectMap[$issuerDN]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向下构造证书链
|
||||
* @param $issuerMap 签发者和证书的映射
|
||||
* @param $certChain 证书链
|
||||
* @param $current 当前需要插入证书链的证书,exclude
|
||||
*/
|
||||
function addressingDown($issuerMap, &$certChain, $current)
|
||||
{
|
||||
$subjectDN = array2string($current['subject']);
|
||||
if (!array_key_exists($subjectDN, $issuerMap)) {
|
||||
return $certChain;
|
||||
}
|
||||
$certChain[] = $issuerMap[$subjectDN];
|
||||
addressingDown($issuerMap, $certChain, $issuerMap[$subjectDN]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract signature from der encoded cert.
|
||||
* Expects x509 der encoded certificate consisting of a section container
|
||||
* containing 2 sections and a bitstream. The bitstream contains the
|
||||
* original encrypted signature, encrypted by the public key of the issuing
|
||||
* signer.
|
||||
* @param string $der
|
||||
* @return string on success
|
||||
* @return bool false on failures
|
||||
*/
|
||||
function extractSignature($der = false)
|
||||
{
|
||||
if (strlen($der) < 5) {
|
||||
return false;
|
||||
}
|
||||
// skip container sequence
|
||||
$der = substr($der, 4);
|
||||
// now burn through two sequences and the return the final bitstream
|
||||
while (strlen($der) > 1) {
|
||||
$class = ord($der[0]);
|
||||
$classHex = dechex($class);
|
||||
switch ($class) {
|
||||
// BITSTREAM
|
||||
case 0x03:
|
||||
$len = ord($der[1]);
|
||||
$bytes = 0;
|
||||
if ($len & 0x80) {
|
||||
$bytes = $len & 0x0f;
|
||||
$len = 0;
|
||||
for ($i = 0; $i < $bytes; $i++) {
|
||||
$len = ($len << 8) | ord($der[$i + 2]);
|
||||
}
|
||||
}
|
||||
return substr($der, 3 + $bytes, $len);
|
||||
break;
|
||||
// SEQUENCE
|
||||
case 0x30:
|
||||
$len = ord($der[1]);
|
||||
$bytes = 0;
|
||||
if ($len & 0x80) {
|
||||
$bytes = $len & 0x0f;
|
||||
$len = 0;
|
||||
for ($i = 0; $i < $bytes; $i++) {
|
||||
$len = ($len << 8) | ord($der[$i + 2]);
|
||||
}
|
||||
}
|
||||
$contents = substr($der, 2 + $bytes, $len);
|
||||
$der = substr($der, 2 + $bytes + $len);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get signature algorithm oid from der encoded signature data.
|
||||
* Expects decrypted signature data from a certificate in der format.
|
||||
* This ASN1 data should contain the following structure:
|
||||
* SEQUENCE
|
||||
* SEQUENCE
|
||||
* OID (signature algorithm)
|
||||
* NULL
|
||||
* OCTET STRING (signature hash)
|
||||
* @return bool false on failures
|
||||
* @return string oid
|
||||
*/
|
||||
function getSignatureAlgorithmOid($der = null)
|
||||
{
|
||||
// Validate this is the der we need...
|
||||
if (!is_string($der) or strlen($der) < 5) {
|
||||
return false;
|
||||
}
|
||||
$bit_seq1 = 0;
|
||||
$bit_seq2 = 2;
|
||||
$bit_oid = 4;
|
||||
if (ord($der[$bit_seq1]) !== 0x30) {
|
||||
die('Invalid DER passed to getSignatureAlgorithmOid()');
|
||||
}
|
||||
if (ord($der[$bit_seq2]) !== 0x30) {
|
||||
die('Invalid DER passed to getSignatureAlgorithmOid()');
|
||||
}
|
||||
if (ord($der[$bit_oid]) !== 0x06) {
|
||||
die('Invalid DER passed to getSignatureAlgorithmOid');
|
||||
}
|
||||
// strip out what we don't need and get the oid
|
||||
$der = substr($der, $bit_oid);
|
||||
// Get the oid
|
||||
$len = ord($der[1]);
|
||||
$bytes = 0;
|
||||
if ($len & 0x80) {
|
||||
$bytes = $len & 0x0f;
|
||||
$len = 0;
|
||||
for ($i = 0; $i < $bytes; $i++) {
|
||||
$len = ($len << 8) | ord($der[$i + 2]);
|
||||
}
|
||||
}
|
||||
$oid_data = substr($der, 2 + $bytes, $len);
|
||||
// Unpack the OID
|
||||
$oid = floor(ord($oid_data[0]) / 40);
|
||||
$oid .= '.' . ord($oid_data[0]) % 40;
|
||||
$value = 0;
|
||||
$i = 1;
|
||||
while ($i < strlen($oid_data)) {
|
||||
$value = $value << 7;
|
||||
$value = $value | (ord($oid_data[$i]) & 0x7f);
|
||||
if (!(ord($oid_data[$i]) & 0x80)) {
|
||||
$oid .= '.' . $value;
|
||||
$value = 0;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return $oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get signature hash from der encoded signature data.
|
||||
* Expects decrypted signature data from a certificate in der format.
|
||||
* This ASN1 data should contain the following structure:
|
||||
* SEQUENCE
|
||||
* SEQUENCE
|
||||
* OID (signature algorithm)
|
||||
* NULL
|
||||
* OCTET STRING (signature hash)
|
||||
* @return bool false on failures
|
||||
* @return string hash
|
||||
*/
|
||||
function getSignatureHash($der = null)
|
||||
{
|
||||
// Validate this is the der we need...
|
||||
if (!is_string($der) or strlen($der) < 5) {
|
||||
return false;
|
||||
}
|
||||
if (ord($der[0]) !== 0x30) {
|
||||
die('Invalid DER passed to getSignatureHash()');
|
||||
}
|
||||
// strip out the container sequence
|
||||
$der = substr($der, 2);
|
||||
if (ord($der[0]) !== 0x30) {
|
||||
die('Invalid DER passed to getSignatureHash()');
|
||||
}
|
||||
// Get the length of the first sequence so we can strip it out.
|
||||
$len = ord($der[1]);
|
||||
$bytes = 0;
|
||||
if ($len & 0x80) {
|
||||
$bytes = $len & 0x0f;
|
||||
$len = 0;
|
||||
for ($i = 0; $i < $bytes; $i++) {
|
||||
$len = ($len << 8) | ord($der[$i + 2]);
|
||||
}
|
||||
}
|
||||
$der = substr($der, 2 + $bytes + $len);
|
||||
// Now we should have an octet string
|
||||
if (ord($der[0]) !== 0x04) {
|
||||
die('Invalid DER passed to getSignatureHash()');
|
||||
}
|
||||
$len = ord($der[1]);
|
||||
$bytes = 0;
|
||||
if ($len & 0x80) {
|
||||
$bytes = $len & 0x0f;
|
||||
$len = 0;
|
||||
for ($i = 0; $i < $bytes; $i++) {
|
||||
$len = ($len << 8) | ord($der[$i + 2]);
|
||||
}
|
||||
}
|
||||
return bin2hex(substr($der, 2 + $bytes, $len));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if one cert was used to sign another
|
||||
* Note that more than one CA cert can give a positive result, some certs
|
||||
* re-issue signing certs after having only changed the expiration dates.
|
||||
* @param string $cert - PEM encoded cert
|
||||
* @param string $caCert - PEM encoded cert that possibly signed $cert
|
||||
* @return bool
|
||||
*/
|
||||
function isCertSigner($certPem = null, $caCertPem = null)
|
||||
{
|
||||
if (!function_exists('openssl_pkey_get_public')) {
|
||||
die('Need the openssl_pkey_get_public() function.');
|
||||
}
|
||||
if (!function_exists('openssl_public_decrypt')) {
|
||||
die('Need the openssl_public_decrypt() function.');
|
||||
}
|
||||
if (!function_exists('hash')) {
|
||||
die('Need the php hash() function.');
|
||||
}
|
||||
if (empty($certPem) or empty($caCertPem)) {
|
||||
return false;
|
||||
}
|
||||
// Convert the cert to der for feeding to extractSignature.
|
||||
$certDer = pemToDer($certPem);
|
||||
if (!is_string($certDer)) {
|
||||
die('invalid certPem');
|
||||
}
|
||||
// Grab the encrypted signature from the der encoded cert.
|
||||
$encryptedSig = extractSignature($certDer);
|
||||
if (!is_string($encryptedSig)) {
|
||||
die('Failed to extract encrypted signature from certPem.');
|
||||
}
|
||||
// Extract the public key from the ca cert, which is what has
|
||||
// been used to encrypt the signature in the cert.
|
||||
$pubKey = openssl_pkey_get_public($caCertPem);
|
||||
if ($pubKey === false) {
|
||||
die('Failed to extract the public key from the ca cert.');
|
||||
}
|
||||
// Attempt to decrypt the encrypted signature using the CA's public
|
||||
// key, returning the decrypted signature in $decryptedSig. If
|
||||
// it can't be decrypted, this ca was not used to sign it for sure...
|
||||
$rc = openssl_public_decrypt($encryptedSig, $decryptedSig, $pubKey);
|
||||
if ($rc === false) {
|
||||
return false;
|
||||
}
|
||||
// We now have the decrypted signature, which is der encoded
|
||||
// asn1 data containing the signature algorithm and signature hash.
|
||||
// Now we need what was originally hashed by the issuer, which is
|
||||
// the original DER encoded certificate without the issuer and
|
||||
// signature information.
|
||||
$origCert = stripSignerAsn($certDer);
|
||||
if ($origCert === false) {
|
||||
die('Failed to extract unsigned cert.');
|
||||
}
|
||||
// Get the oid of the signature hash algorithm, which is required
|
||||
// to generate our own hash of the original cert. This hash is
|
||||
// what will be compared to the issuers hash.
|
||||
$oid = getSignatureAlgorithmOid($decryptedSig);
|
||||
if ($oid === false) {
|
||||
die('Failed to determine the signature algorithm.');
|
||||
}
|
||||
switch ($oid) {
|
||||
case '1.2.840.113549.2.2':
|
||||
$algo = 'md2';
|
||||
break;
|
||||
case '1.2.840.113549.2.4':
|
||||
$algo = 'md4';
|
||||
break;
|
||||
case '1.2.840.113549.2.5':
|
||||
$algo = 'md5';
|
||||
break;
|
||||
case '1.3.14.3.2.18':
|
||||
$algo = 'sha';
|
||||
break;
|
||||
case '1.3.14.3.2.26':
|
||||
$algo = 'sha1';
|
||||
break;
|
||||
case '2.16.840.1.101.3.4.2.1':
|
||||
$algo = 'sha256';
|
||||
break;
|
||||
case '2.16.840.1.101.3.4.2.2':
|
||||
$algo = 'sha384';
|
||||
break;
|
||||
case '2.16.840.1.101.3.4.2.3':
|
||||
$algo = 'sha512';
|
||||
break;
|
||||
default:
|
||||
die('Unknown signature hash algorithm oid: ' . $oid);
|
||||
break;
|
||||
}
|
||||
// Get the issuer generated hash from the decrypted signature.
|
||||
$decryptedHash = getSignatureHash($decryptedSig);
|
||||
// Ok, hash the original unsigned cert with the same algorithm
|
||||
// and if it matches $decryptedHash we have a winner.
|
||||
$certHash = hash($algo, $origCert);
|
||||
return ($decryptedHash === $certHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert pem encoded certificate to DER encoding
|
||||
* @return string $derEncoded on success
|
||||
* @return bool false on failures
|
||||
*/
|
||||
function pemToDer($pem = null)
|
||||
{
|
||||
if (!is_string($pem)) {
|
||||
return false;
|
||||
}
|
||||
$cert_split = preg_split('/(-----((BEGIN)|(END)) CERTIFICATE-----)/', $pem);
|
||||
if (!isset($cert_split[1])) {
|
||||
return false;
|
||||
}
|
||||
return base64_decode($cert_split[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain der cert with issuer and signature sections stripped.
|
||||
* @param string $der - der encoded certificate
|
||||
* @return string $der on success
|
||||
* @return bool false on failures.
|
||||
*/
|
||||
function stripSignerAsn($der = null)
|
||||
{
|
||||
if (!is_string($der) or strlen($der) < 8) {
|
||||
return false;
|
||||
}
|
||||
$bit = 4;
|
||||
$len = ord($der[($bit + 1)]);
|
||||
$bytes = 0;
|
||||
if ($len & 0x80) {
|
||||
$bytes = $len & 0x0f;
|
||||
$len = 0;
|
||||
for ($i = 0; $i < $bytes; $i++) {
|
||||
$len = ($len << 8) | ord($der[$bit + $i + 2]);
|
||||
}
|
||||
}
|
||||
return substr($der, 4, $len + 4);
|
||||
}
|
||||
1334
extend/AliPayV2/alipay-sdk/aopV2/AopClient.php
Normal file
1334
extend/AliPayV2/alipay-sdk/aopV2/AopClient.php
Normal file
File diff suppressed because it is too large
Load Diff
78
extend/AliPayV2/alipay-sdk/aopV2/AopEncrypt.php
Normal file
78
extend/AliPayV2/alipay-sdk/aopV2/AopEncrypt.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* 加密工具类
|
||||
*
|
||||
* User: jiehua
|
||||
* Date: 16/3/30
|
||||
* Time: 下午3:25
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
function encrypt($str, $screct_key)
|
||||
{
|
||||
//AES, 128 模式加密数据 CBC
|
||||
$screct_key = base64_decode($screct_key);
|
||||
$str = trim($str);
|
||||
$str = addPKCS7Padding($str);
|
||||
|
||||
//设置全0的IV
|
||||
|
||||
$iv = str_repeat("\0", 16);
|
||||
$encrypt_str = openssl_encrypt($str, 'aes-128-cbc', $screct_key, OPENSSL_NO_PADDING, $iv);
|
||||
return base64_encode($encrypt_str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
function decrypt($str, $screct_key)
|
||||
{
|
||||
//AES, 128 模式加密数据 CBC
|
||||
$str = base64_decode($str);
|
||||
$screct_key = base64_decode($screct_key);
|
||||
|
||||
//设置全0的IV
|
||||
$iv = str_repeat("\0", 16);
|
||||
$decrypt_str = openssl_decrypt($str, 'aes-128-cbc', $screct_key, OPENSSL_NO_PADDING, $iv);
|
||||
$decrypt_str = stripPKSC7Padding($decrypt_str);
|
||||
return $decrypt_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充算法
|
||||
* @param string $source
|
||||
* @return string
|
||||
*/
|
||||
function addPKCS7Padding($source)
|
||||
{
|
||||
$source = trim($source);
|
||||
$block = 16;
|
||||
|
||||
$pad = $block - (strlen($source) % $block);
|
||||
if ($pad <= $block) {
|
||||
$char = chr($pad);
|
||||
$source .= str_repeat($char, $pad);
|
||||
}
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移去填充算法
|
||||
* @param string $source
|
||||
* @return string
|
||||
*/
|
||||
function stripPKSC7Padding($source)
|
||||
{
|
||||
$char = substr($source, -1);
|
||||
$num = ord($char);
|
||||
if ($num == 62) return $source;
|
||||
$source = substr($source, 0, -$num);
|
||||
return $source;
|
||||
}
|
||||
18
extend/AliPayV2/alipay-sdk/aopV2/EncryptParseItem.php
Normal file
18
extend/AliPayV2/alipay-sdk/aopV2/EncryptParseItem.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* TODO 补充说明
|
||||
*
|
||||
* User: jiehua
|
||||
* Date: 16/3/30
|
||||
* Time: 下午8:55
|
||||
*/
|
||||
|
||||
class EncryptParseItem
|
||||
{
|
||||
public $startIndex;
|
||||
|
||||
public $endIndex;
|
||||
|
||||
public $encryptContent;
|
||||
|
||||
}
|
||||
16
extend/AliPayV2/alipay-sdk/aopV2/EncryptResponseData.php
Normal file
16
extend/AliPayV2/alipay-sdk/aopV2/EncryptResponseData.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* TODO 补充说明
|
||||
*
|
||||
* User: jiehua
|
||||
* Date: 16/3/30
|
||||
* Time: 下午8:51
|
||||
*/
|
||||
|
||||
class EncryptResponseData
|
||||
{
|
||||
public $realContent;
|
||||
|
||||
public $returnContent;
|
||||
|
||||
}
|
||||
15
extend/AliPayV2/alipay-sdk/aopV2/SignData.php
Normal file
15
extend/AliPayV2/alipay-sdk/aopV2/SignData.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: jiehua
|
||||
* Date: 15/5/2
|
||||
* Time: 下午6:21
|
||||
*/
|
||||
|
||||
class SignData
|
||||
{
|
||||
public $signSourceData = null;
|
||||
|
||||
public $sign = null;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* ALIPAY API: alipay.system.oauth.token request
|
||||
*
|
||||
* @author auto create
|
||||
* @since 1.0, 2024-03-01 16:28:47
|
||||
*/
|
||||
class AlipaySystemOauthTokenRequest
|
||||
{
|
||||
/**
|
||||
* 授权码,用户对应用授权后得到。本参数在 grant_type 为 authorization_code 时必填;为 refresh_token 时不填。
|
||||
**/
|
||||
private $code;
|
||||
|
||||
/**
|
||||
* 授权方式
|
||||
**/
|
||||
private $grantType;
|
||||
|
||||
/**
|
||||
* 刷新令牌,上次换取访问令牌时得到。本参数在 grant_type 为 authorization_code 时不填;为 refresh_token 时必填,且该值来源于此接口的返回值 app_refresh_token(即至少需要通过 grant_type=authorization_code 调用此接口一次才能获取)。
|
||||
**/
|
||||
private $refreshToken;
|
||||
|
||||
private $apiParas = array();
|
||||
private $terminalType;
|
||||
private $terminalInfo;
|
||||
private $prodCode;
|
||||
private $apiVersion="1.0";
|
||||
private $notifyUrl;
|
||||
private $returnUrl;
|
||||
private $needEncrypt=false;
|
||||
|
||||
|
||||
public function setCode($code)
|
||||
{
|
||||
$this->code = $code;
|
||||
$this->apiParas["code"] = $code;
|
||||
}
|
||||
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function setGrantType($grantType)
|
||||
{
|
||||
$this->grantType = $grantType;
|
||||
$this->apiParas["grant_type"] = $grantType;
|
||||
}
|
||||
|
||||
public function getGrantType()
|
||||
{
|
||||
return $this->grantType;
|
||||
}
|
||||
|
||||
public function setRefreshToken($refreshToken)
|
||||
{
|
||||
$this->refreshToken = $refreshToken;
|
||||
$this->apiParas["refresh_token"] = $refreshToken;
|
||||
}
|
||||
|
||||
public function getRefreshToken()
|
||||
{
|
||||
return $this->refreshToken;
|
||||
}
|
||||
|
||||
public function getApiMethodName()
|
||||
{
|
||||
return "alipay.system.oauth.token";
|
||||
}
|
||||
|
||||
public function setNotifyUrl($notifyUrl)
|
||||
{
|
||||
$this->notifyUrl=$notifyUrl;
|
||||
}
|
||||
|
||||
public function getNotifyUrl()
|
||||
{
|
||||
return $this->notifyUrl;
|
||||
}
|
||||
|
||||
public function setReturnUrl($returnUrl)
|
||||
{
|
||||
$this->returnUrl=$returnUrl;
|
||||
}
|
||||
|
||||
public function getReturnUrl()
|
||||
{
|
||||
return $this->returnUrl;
|
||||
}
|
||||
|
||||
public function getApiParas()
|
||||
{
|
||||
return $this->apiParas;
|
||||
}
|
||||
|
||||
public function getTerminalType()
|
||||
{
|
||||
return $this->terminalType;
|
||||
}
|
||||
|
||||
public function setTerminalType($terminalType)
|
||||
{
|
||||
$this->terminalType = $terminalType;
|
||||
}
|
||||
|
||||
public function getTerminalInfo()
|
||||
{
|
||||
return $this->terminalInfo;
|
||||
}
|
||||
|
||||
public function setTerminalInfo($terminalInfo)
|
||||
{
|
||||
$this->terminalInfo = $terminalInfo;
|
||||
}
|
||||
|
||||
public function getProdCode()
|
||||
{
|
||||
return $this->prodCode;
|
||||
}
|
||||
|
||||
public function setProdCode($prodCode)
|
||||
{
|
||||
$this->prodCode = $prodCode;
|
||||
}
|
||||
|
||||
public function setApiVersion($apiVersion)
|
||||
{
|
||||
$this->apiVersion=$apiVersion;
|
||||
}
|
||||
|
||||
public function getApiVersion()
|
||||
{
|
||||
return $this->apiVersion;
|
||||
}
|
||||
|
||||
public function setNeedEncrypt($needEncrypt)
|
||||
{
|
||||
|
||||
$this->needEncrypt=$needEncrypt;
|
||||
|
||||
}
|
||||
|
||||
public function getNeedEncrypt()
|
||||
{
|
||||
return $this->needEncrypt;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* ALIPAY API: alipay.trade.app.pay request
|
||||
*
|
||||
* @author auto create
|
||||
* @since 1.0, 2024-12-11 16:02:21
|
||||
*/
|
||||
class AlipayTradeAppPayRequest
|
||||
{
|
||||
/**
|
||||
* app支付接口2.0
|
||||
**/
|
||||
private $bizContent;
|
||||
|
||||
private $apiParas = array();
|
||||
private $terminalType;
|
||||
private $terminalInfo;
|
||||
private $prodCode;
|
||||
private $apiVersion="1.0";
|
||||
private $notifyUrl;
|
||||
private $returnUrl;
|
||||
private $needEncrypt=false;
|
||||
|
||||
|
||||
public function setBizContent($bizContent)
|
||||
{
|
||||
$this->bizContent = $bizContent;
|
||||
$this->apiParas["biz_content"] = $bizContent;
|
||||
}
|
||||
|
||||
public function getBizContent()
|
||||
{
|
||||
return $this->bizContent;
|
||||
}
|
||||
|
||||
public function getApiMethodName()
|
||||
{
|
||||
return "alipay.trade.app.pay";
|
||||
}
|
||||
|
||||
public function setNotifyUrl($notifyUrl)
|
||||
{
|
||||
$this->notifyUrl=$notifyUrl;
|
||||
}
|
||||
|
||||
public function getNotifyUrl()
|
||||
{
|
||||
return $this->notifyUrl;
|
||||
}
|
||||
|
||||
public function setReturnUrl($returnUrl)
|
||||
{
|
||||
$this->returnUrl=$returnUrl;
|
||||
}
|
||||
|
||||
public function getReturnUrl()
|
||||
{
|
||||
return $this->returnUrl;
|
||||
}
|
||||
|
||||
public function getApiParas()
|
||||
{
|
||||
return $this->apiParas;
|
||||
}
|
||||
|
||||
public function getTerminalType()
|
||||
{
|
||||
return $this->terminalType;
|
||||
}
|
||||
|
||||
public function setTerminalType($terminalType)
|
||||
{
|
||||
$this->terminalType = $terminalType;
|
||||
}
|
||||
|
||||
public function getTerminalInfo()
|
||||
{
|
||||
return $this->terminalInfo;
|
||||
}
|
||||
|
||||
public function setTerminalInfo($terminalInfo)
|
||||
{
|
||||
$this->terminalInfo = $terminalInfo;
|
||||
}
|
||||
|
||||
public function getProdCode()
|
||||
{
|
||||
return $this->prodCode;
|
||||
}
|
||||
|
||||
public function setProdCode($prodCode)
|
||||
{
|
||||
$this->prodCode = $prodCode;
|
||||
}
|
||||
|
||||
public function setApiVersion($apiVersion)
|
||||
{
|
||||
$this->apiVersion=$apiVersion;
|
||||
}
|
||||
|
||||
public function getApiVersion()
|
||||
{
|
||||
return $this->apiVersion;
|
||||
}
|
||||
|
||||
public function setNeedEncrypt($needEncrypt)
|
||||
{
|
||||
|
||||
$this->needEncrypt=$needEncrypt;
|
||||
|
||||
}
|
||||
|
||||
public function getNeedEncrypt()
|
||||
{
|
||||
return $this->needEncrypt;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* ALIPAY API: alipay.trade.query request
|
||||
*
|
||||
* @author auto create
|
||||
* @since 1.0, 2024-12-25 16:17:22
|
||||
*/
|
||||
class AlipayTradeQueryRequest
|
||||
{
|
||||
/**
|
||||
* 统一收单线下交易查询
|
||||
修改路由策略到R
|
||||
**/
|
||||
private $bizContent;
|
||||
|
||||
private $apiParas = array();
|
||||
private $terminalType;
|
||||
private $terminalInfo;
|
||||
private $prodCode;
|
||||
private $apiVersion="1.0";
|
||||
private $notifyUrl;
|
||||
private $returnUrl;
|
||||
private $needEncrypt=false;
|
||||
|
||||
|
||||
public function setBizContent($bizContent)
|
||||
{
|
||||
$this->bizContent = $bizContent;
|
||||
$this->apiParas["biz_content"] = $bizContent;
|
||||
}
|
||||
|
||||
public function getBizContent()
|
||||
{
|
||||
return $this->bizContent;
|
||||
}
|
||||
|
||||
public function getApiMethodName()
|
||||
{
|
||||
return "alipay.trade.query";
|
||||
}
|
||||
|
||||
public function setNotifyUrl($notifyUrl)
|
||||
{
|
||||
$this->notifyUrl=$notifyUrl;
|
||||
}
|
||||
|
||||
public function getNotifyUrl()
|
||||
{
|
||||
return $this->notifyUrl;
|
||||
}
|
||||
|
||||
public function setReturnUrl($returnUrl)
|
||||
{
|
||||
$this->returnUrl=$returnUrl;
|
||||
}
|
||||
|
||||
public function getReturnUrl()
|
||||
{
|
||||
return $this->returnUrl;
|
||||
}
|
||||
|
||||
public function getApiParas()
|
||||
{
|
||||
return $this->apiParas;
|
||||
}
|
||||
|
||||
public function getTerminalType()
|
||||
{
|
||||
return $this->terminalType;
|
||||
}
|
||||
|
||||
public function setTerminalType($terminalType)
|
||||
{
|
||||
$this->terminalType = $terminalType;
|
||||
}
|
||||
|
||||
public function getTerminalInfo()
|
||||
{
|
||||
return $this->terminalInfo;
|
||||
}
|
||||
|
||||
public function setTerminalInfo($terminalInfo)
|
||||
{
|
||||
$this->terminalInfo = $terminalInfo;
|
||||
}
|
||||
|
||||
public function getProdCode()
|
||||
{
|
||||
return $this->prodCode;
|
||||
}
|
||||
|
||||
public function setProdCode($prodCode)
|
||||
{
|
||||
$this->prodCode = $prodCode;
|
||||
}
|
||||
|
||||
public function setApiVersion($apiVersion)
|
||||
{
|
||||
$this->apiVersion=$apiVersion;
|
||||
}
|
||||
|
||||
public function getApiVersion()
|
||||
{
|
||||
return $this->apiVersion;
|
||||
}
|
||||
|
||||
public function setNeedEncrypt($needEncrypt)
|
||||
{
|
||||
|
||||
$this->needEncrypt=$needEncrypt;
|
||||
|
||||
}
|
||||
|
||||
public function getNeedEncrypt()
|
||||
{
|
||||
return $this->needEncrypt;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* ALIPAY API: alipay.user.info.share request
|
||||
*
|
||||
* @author auto create
|
||||
* @since 1.0, 2025-02-13 15:12:20
|
||||
*/
|
||||
class AlipayUserInfoShareRequest
|
||||
{
|
||||
|
||||
private $apiParas = array();
|
||||
private $terminalType;
|
||||
private $terminalInfo;
|
||||
private $prodCode;
|
||||
private $apiVersion="1.0";
|
||||
private $notifyUrl;
|
||||
private $returnUrl;
|
||||
private $needEncrypt=false;
|
||||
|
||||
|
||||
public function getApiMethodName()
|
||||
{
|
||||
return "alipay.user.info.share";
|
||||
}
|
||||
|
||||
public function setNotifyUrl($notifyUrl)
|
||||
{
|
||||
$this->notifyUrl=$notifyUrl;
|
||||
}
|
||||
|
||||
public function getNotifyUrl()
|
||||
{
|
||||
return $this->notifyUrl;
|
||||
}
|
||||
|
||||
public function setReturnUrl($returnUrl)
|
||||
{
|
||||
$this->returnUrl=$returnUrl;
|
||||
}
|
||||
|
||||
public function getReturnUrl()
|
||||
{
|
||||
return $this->returnUrl;
|
||||
}
|
||||
|
||||
public function getApiParas()
|
||||
{
|
||||
return $this->apiParas;
|
||||
}
|
||||
|
||||
public function getTerminalType()
|
||||
{
|
||||
return $this->terminalType;
|
||||
}
|
||||
|
||||
public function setTerminalType($terminalType)
|
||||
{
|
||||
$this->terminalType = $terminalType;
|
||||
}
|
||||
|
||||
public function getTerminalInfo()
|
||||
{
|
||||
return $this->terminalInfo;
|
||||
}
|
||||
|
||||
public function setTerminalInfo($terminalInfo)
|
||||
{
|
||||
$this->terminalInfo = $terminalInfo;
|
||||
}
|
||||
|
||||
public function getProdCode()
|
||||
{
|
||||
return $this->prodCode;
|
||||
}
|
||||
|
||||
public function setProdCode($prodCode)
|
||||
{
|
||||
$this->prodCode = $prodCode;
|
||||
}
|
||||
|
||||
public function setApiVersion($apiVersion)
|
||||
{
|
||||
$this->apiVersion=$apiVersion;
|
||||
}
|
||||
|
||||
public function getApiVersion()
|
||||
{
|
||||
return $this->apiVersion;
|
||||
}
|
||||
|
||||
public function setNeedEncrypt($needEncrypt)
|
||||
{
|
||||
|
||||
$this->needEncrypt=$needEncrypt;
|
||||
|
||||
}
|
||||
|
||||
public function getNeedEncrypt()
|
||||
{
|
||||
return $this->needEncrypt;
|
||||
}
|
||||
|
||||
}
|
||||
114
extend/AliPayV2/alipay-sdk/aopV2/schema/AttributeRule.php
Normal file
114
extend/AliPayV2/alipay-sdk/aopV2/schema/AttributeRule.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
class AttributeRule
|
||||
{
|
||||
private $type;
|
||||
private $name;
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function __construct($type = null, $name = null, $value = null)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function checkRuleType($ruleType)
|
||||
{
|
||||
$ruleTypeArr = array(
|
||||
"required" => "是否必填,true/false",
|
||||
"maxLength" => "字符串要求最大长度",
|
||||
"minLength" => "字符串要求最小长度",
|
||||
"exclusiveMaximum" => "最大值,包含最大值,<=",
|
||||
"exclusiveMinimum" => "最小值,包含最小值,>=",
|
||||
"maximum" => "最大值,不包含最大值,<",
|
||||
"minimum" => "最小值,不包含最小值,>",
|
||||
"maxSize" => "最大个数",
|
||||
"minSize" => "最大个数",
|
||||
"precision" => "精度",
|
||||
"pattern" => "正则表达式",
|
||||
"valueType" => "值类型",
|
||||
"devTip" => "输入提示",
|
||||
"height" => "高度",
|
||||
"width" => "长度",
|
||||
"urlSchema" => "url格式"
|
||||
);
|
||||
if (empty($ruleType)) return false;
|
||||
if (array_key_exists($ruleType, $ruleTypeArr)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function toElement($dom, $parent, $attributeId)
|
||||
{
|
||||
if (empty($this->name) && $this->name != '0') {
|
||||
throw new \Exception("id=[" . $attributeId . "] AttrRule格式错误!AttrRule缺少name!");
|
||||
}
|
||||
if (!$this->checkRuleType($this->type)) {
|
||||
throw new \Exception("id=[" . $attributeId . "] AttrRule类型type不合法!");
|
||||
}
|
||||
if (empty($this->value) && $this->value != '0') {
|
||||
throw new \Exception("id=[" . $attributeId . "] AttrRule格式错误!AttrRule缺少value!");
|
||||
}
|
||||
$rule = $dom->createElement("rule");
|
||||
$rule->setAttribute("name", $this->name);
|
||||
$rule->setAttribute("type", $this->type);
|
||||
$rule->setAttribute("value", $this->value);
|
||||
$parent->appendChild($rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $type
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
||||
66
extend/AliPayV2/alipay-sdk/aopV2/schema/Option.php
Normal file
66
extend/AliPayV2/alipay-sdk/aopV2/schema/Option.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
class Option
|
||||
{
|
||||
private $displayName;
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @param $displayName
|
||||
* @param $value
|
||||
*/
|
||||
public function __construct($displayName = null, $value = null)
|
||||
{
|
||||
$this->displayName = $displayName;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function toElement($dom, $parent, $attributeId)
|
||||
{
|
||||
if (empty($this->displayName) && $this->displayName != '0') {
|
||||
throw new \Exception("id=[" . $attributeId . "] Option格式错误!Option名称displayName不能为空!");
|
||||
}
|
||||
if (empty($this->value) && $this->value != '0') {
|
||||
throw new \Exception("id=[" . $attributeId . "] Option格式错误!Option的值value不能为空!");
|
||||
}
|
||||
$option = $dom->createElement("option");
|
||||
$option->setAttribute("displayName", $this->displayName);
|
||||
$option->setAttribute("value", $this->value);
|
||||
$parent->appendChild($option);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $displayName
|
||||
*/
|
||||
public function setDisplayName($displayName)
|
||||
{
|
||||
$this->displayName = $displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
require_once 'XMLAttribute.php';
|
||||
require_once 'AttributeRule.php';
|
||||
require_once 'Option.php';
|
||||
|
||||
class ServiceSchemaFactory
|
||||
{
|
||||
public static function createAttribute($id = null, $name = null, $type = null, $valueType = null)
|
||||
{
|
||||
$attribute = new XMLAttribute();
|
||||
$attribute->setId($id);
|
||||
$attribute->setName($name);
|
||||
$attribute->setType($type);
|
||||
$attribute->setValueType($valueType);
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
public static function createRule($type = null, $name = null, $value = null)
|
||||
{
|
||||
return new AttributeRule($type, $name, $value);
|
||||
}
|
||||
|
||||
public static function createOption($displayName = null, $value = null)
|
||||
{
|
||||
return new Option($displayName, $value);
|
||||
}
|
||||
}
|
||||
256
extend/AliPayV2/alipay-sdk/aopV2/schema/ServiceSchemaReader.php
Normal file
256
extend/AliPayV2/alipay-sdk/aopV2/schema/ServiceSchemaReader.php
Normal file
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
require_once 'XMLAttribute.php';
|
||||
require_once 'AttributeRule.php';
|
||||
require_once 'Option.php';
|
||||
require_once 'ServiceSchemaFactory.php';
|
||||
|
||||
class ServiceSchemaReader
|
||||
{
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function readXmlForArrayByFile($filePath)
|
||||
{
|
||||
set_error_handler('ServiceSchemaReader::errorHandler');
|
||||
$dom = new DOMDocument('1.0', 'utf-8');
|
||||
try {
|
||||
$dom->load($filePath);
|
||||
} catch (Exception $e) {
|
||||
throw new \Exception("XML格式错误,无法正常解析!");
|
||||
}
|
||||
return self::readXmlForList($dom->documentElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function readXmlForArrayByString($xmlString)
|
||||
{
|
||||
set_error_handler('ServiceSchemaReader::errorHandler');
|
||||
$dom = new DOMDocument('1.0', 'utf-8');
|
||||
try {
|
||||
$dom->loadXML($xmlString);
|
||||
} catch (Exception $e) {
|
||||
throw new \Exception("XML格式错误,无法正常解析!");
|
||||
}
|
||||
return self::readXmlForList($dom->documentElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function readXmlForList(DOMElement $rootEle)
|
||||
{
|
||||
$attributeArr = array();
|
||||
foreach ($rootEle->getElementsByTagName('attribute') as $item) {
|
||||
if ($item->parentNode === $rootEle) {
|
||||
$attribute = self::elementToAttribute($item);
|
||||
$attributeArr[$attribute->getId()] = $attribute;
|
||||
}
|
||||
}
|
||||
return $attributeArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function elementToAttribute($attributeElm)
|
||||
{
|
||||
$attributeId = $attributeElm->getAttribute("id");
|
||||
if (self::checkEmpty($attributeId)) {
|
||||
throw new \Exception("Attribute属性缺少id! 节点路径 [" . $attributeElm->getNodePath() . "]");
|
||||
}
|
||||
$attributeName = $attributeElm->getAttribute("name");
|
||||
$attributeType = $attributeElm->getAttribute("type");
|
||||
if (self::checkEmpty($attributeType)) {
|
||||
throw new \Exception("Attribute属性缺少type! 节点路径 [" . $attributeElm->getNodePath() . "].attributeId=" . $attributeId);
|
||||
}
|
||||
|
||||
$valueType = $attributeElm->getAttribute("valueType");
|
||||
$attribute = ServiceSchemaFactory::createAttribute($attributeId, $attributeName, $attributeType, $valueType);
|
||||
if (!$attribute->checkAttributeValueType($valueType)) {
|
||||
throw new \Exception("Attribute属性valueType不正确! 节点路径 [" . $attributeElm->getNodePath() . "].attributeId=" . $attributeId);
|
||||
}
|
||||
|
||||
if ("single" === $attributeType) {
|
||||
ServiceSchemaReader::elementToSingleAttribute($attributeElm, $attribute);
|
||||
} elseif ("multi" === $attributeType) {
|
||||
ServiceSchemaReader::elementToMultiAttribute($attributeElm, $attribute);
|
||||
} elseif ("complex" === $attributeType) {
|
||||
ServiceSchemaReader::elementToComplexAttribute($attributeElm, $attribute);
|
||||
} elseif ("multiComplex" === $attributeType) {
|
||||
ServiceSchemaReader::elementToMultiComplexAttribute($attributeElm, $attribute);
|
||||
} else {
|
||||
throw new \Exception("Attribute属性type类型不正确! 节点路径 [" . $attributeElm->getNodePath() . "].attributeId=" . $attributeId);
|
||||
}
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function elementToSingleAttribute($attributeElm, $attribute)
|
||||
{
|
||||
self::elementToRule($attributeElm, $attribute);
|
||||
self::elementToOption($attributeElm, $attribute);
|
||||
foreach ($attributeElm->getElementsByTagName('value') as $value) {
|
||||
if ($value->parentNode === $attributeElm) {
|
||||
$attribute->setValues($value->nodeValue);
|
||||
//只取第一个<value>标签
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function elementToMultiAttribute($attributeElm, $attribute)
|
||||
{
|
||||
self::elementToRule($attributeElm, $attribute);
|
||||
self::elementToOption($attributeElm, $attribute);
|
||||
foreach ($attributeElm->getElementsByTagName('values') as $values) {
|
||||
if ($values->parentNode === $attributeElm) {
|
||||
$valueArr = array();
|
||||
foreach ($values->getElementsByTagName('value') as $value) {
|
||||
if ($value->parentNode === $values) {
|
||||
$valueArr[] = $value->nodeValue;
|
||||
}
|
||||
}
|
||||
$attribute->setValues($valueArr);
|
||||
//只取第一个<values>标签
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function elementToComplexAttribute($attributeElm, $attribute)
|
||||
{
|
||||
self::elementToRule($attributeElm, $attribute);
|
||||
foreach ($attributeElm->getElementsByTagName('attributes') as $attributes) {
|
||||
if ($attributes->parentNode === $attributeElm) {
|
||||
$attributeArr = array();
|
||||
foreach ($attributes->getElementsByTagName('attribute') as $item) {
|
||||
if ($item->parentNode === $attributes) {
|
||||
$attributeType = $item->getAttribute("type");
|
||||
if ("single" === $attributeType || "multi" === $attributeType) {
|
||||
$attributeArr[] = self::elementToAttribute($item);
|
||||
}
|
||||
} else {
|
||||
throw new \Exception("Attribute属性type类型不正确! 节点路径 [" . $item->getNodePath() . "]");
|
||||
}
|
||||
}
|
||||
$attribute->setValues($attributeArr);
|
||||
//只取第一个<attributes>标签
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function elementToMultiComplexAttribute($attributeElm, $attribute)
|
||||
{
|
||||
$attributeArr = array();
|
||||
foreach ($attributeElm->getElementsByTagName('attributes') as $attributes) {
|
||||
if ($attributes->parentNode === $attributeElm) {
|
||||
$complexAttr = new XMLAttribute();//每一个$complexAttr都是一个ComplexAttribute对象
|
||||
$valuesArr = array();
|
||||
foreach ($attributes->getElementsByTagName('attribute') as $item) {
|
||||
if ($item->parentNode === $attributes) {
|
||||
$attributeType = $item->getAttribute("type");
|
||||
if ("single" === $attributeType || "multi" === $attributeType) {
|
||||
$valuesArr[] = self::elementToAttribute($item);
|
||||
}
|
||||
} else {
|
||||
throw new \Exception("Attribute属性type类型不正确! 节点路径 [" . $item->getNodePath() . "]");
|
||||
}
|
||||
}
|
||||
$complexAttr->setValues($valuesArr);
|
||||
$attributeArr[] = $complexAttr;
|
||||
}
|
||||
}
|
||||
$attribute->setValues($attributeArr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function elementToRule($attributeElm, $attribute)
|
||||
{
|
||||
foreach ($attributeElm->getElementsByTagName('rules') as $rules) {
|
||||
if ($rules->parentNode === $attributeElm) {
|
||||
$ruleArr = array();
|
||||
foreach ($rules->getElementsByTagName('rule') as $rule) {
|
||||
if ($rule->parentNode === $rules) {
|
||||
$ruleType = $rule->getAttribute("type");
|
||||
$ruleName = $rule->getAttribute("name");
|
||||
$ruleValue = $rule->getAttribute("value");
|
||||
if (self::checkEmpty($ruleValue)) {
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] AttrRule格式错误!AttrRule缺少value!");
|
||||
}
|
||||
$ruleObj = ServiceSchemaFactory::createRule($ruleType, $ruleName, $ruleValue);
|
||||
if (!$ruleObj->checkRuleType($ruleType)) {
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] AttrRule类型type不合法!");
|
||||
}
|
||||
$ruleArr[] = $ruleObj;
|
||||
}
|
||||
}
|
||||
$attribute->setRules($ruleArr);
|
||||
//只取第一个<rules>标签
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function elementToOption($attributeElm, $attribute)
|
||||
{
|
||||
foreach ($attributeElm->getElementsByTagName('options') as $options) {
|
||||
if ($options->parentNode === $attributeElm) {
|
||||
$optionsArr = array();
|
||||
foreach ($options->getElementsByTagName('option') as $option) {
|
||||
if ($option->parentNode === $options) {
|
||||
$displayName = $option->getAttribute("displayName");
|
||||
if (self::checkEmpty($displayName)) {
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] Option格式错误!Option名称displayName不能为空!");
|
||||
}
|
||||
$value = $option->getAttribute("value");
|
||||
if (self::checkEmpty($value)) {
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] Option格式错误!Option的值value不能为空!");
|
||||
}
|
||||
$optionObj = ServiceSchemaFactory::createOption($displayName, $value);
|
||||
$optionsArr[] = $optionObj;
|
||||
}
|
||||
}
|
||||
$attribute->setOptions($optionsArr);
|
||||
//只取第一个<options>标签
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function checkEmpty($value)
|
||||
{
|
||||
if (is_null($value))
|
||||
return true;
|
||||
if (trim($value) == "")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
static function errorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
throw new \Exception($errstr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class ServiceSchemaWriter
|
||||
{
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function writeSchemaXmlString(array $attributesArr)
|
||||
{
|
||||
$dom = new DOMDocument('1.0', 'utf-8');
|
||||
$root = $dom->createElement("serviceSchema");
|
||||
foreach ($attributesArr as $attribute) {
|
||||
if ($attribute instanceof XMLAttribute) {
|
||||
$attribute->toValueElement($dom, $root);
|
||||
}
|
||||
}
|
||||
$dom->appendChild($root);
|
||||
return $dom->saveXML($dom->documentElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function writeFullchemaXmlString(array $attributesArr)
|
||||
{
|
||||
$dom = new DOMDocument('1.0', 'utf-8');
|
||||
$root = $dom->createElement("serviceSchema");
|
||||
foreach ($attributesArr as $attribute) {
|
||||
if ($attribute instanceof XMLAttribute) {
|
||||
$attribute->toElement($dom, $root);
|
||||
}
|
||||
}
|
||||
$dom->appendChild($root);
|
||||
return $dom->saveXML($dom->documentElement);
|
||||
}
|
||||
}
|
||||
342
extend/AliPayV2/alipay-sdk/aopV2/schema/XMLAttribute.php
Normal file
342
extend/AliPayV2/alipay-sdk/aopV2/schema/XMLAttribute.php
Normal file
@@ -0,0 +1,342 @@
|
||||
<?php
|
||||
|
||||
class XMLAttribute
|
||||
{
|
||||
private $id;
|
||||
private $name;
|
||||
private $type;
|
||||
private $valueType;
|
||||
private $rules;
|
||||
private $options;
|
||||
private $values;
|
||||
|
||||
public function checkAttributeValueType($attributeValueType)
|
||||
{
|
||||
$valueTypeArr = array(
|
||||
"text" => "文本类型",
|
||||
"boolean" => "boolean类型",
|
||||
"numeric" => "数据类型",
|
||||
"enum" => "枚举型",
|
||||
"object" => "对象型"
|
||||
);
|
||||
if (empty($attributeValueType)) return false;
|
||||
// foreach ($valueTypeArr as $key => $value){
|
||||
// if($attributeValueType === $key) return true;
|
||||
// }
|
||||
if (array_key_exists($attributeValueType, $valueTypeArr)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function toElement($dom, $parent)
|
||||
{
|
||||
$this->checkAttribute();
|
||||
if ("single" === $this->type || "multi" === $this->type) {
|
||||
$attributeElm = $this->appendAttributeValues($dom, $parent, $this);
|
||||
$this->appendRulesElement($dom, $attributeElm, $this->rules, $this->id);
|
||||
$this->appendOptionsElement($dom, $attributeElm, $this->options, $this->id);
|
||||
} elseif ("complex" === $this->type) {
|
||||
$attributeElm = $dom->createElement("attribute");
|
||||
$attributeElm->setAttribute("id", $this->id);
|
||||
$attributeElm->setAttribute("type", $this->type);
|
||||
if ($this->name != "" && !is_null($this->name)) {
|
||||
$attributeElm->setAttribute("name", $this->name);
|
||||
}
|
||||
if ($this->checkAttributeValueType($this->valueType)) {
|
||||
$attributeElm->setAttribute("valueType", $this->valueType);
|
||||
}
|
||||
|
||||
$attributesElm = $dom->createElement("attributes");
|
||||
if (is_array($this->values)) {
|
||||
foreach ($this->values as $attribute) {
|
||||
if ($attribute instanceof XMLAttribute) {
|
||||
$attributeElmTmp = $this->appendAttributeValues($dom, $attributesElm, $attribute);
|
||||
$this->appendRulesElement($dom, $attributeElmTmp, $attribute->rules, $attribute->id);
|
||||
$this->appendOptionsElement($dom, $attributeElmTmp, $attribute->options, $attribute->id);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($this->values)) {//complex类型的values必须是数组 或 空
|
||||
throw new \Exception("id=[" . $this->id . "] XMLAttribute属性values不合法!");
|
||||
}
|
||||
$attributeElm->appendChild($attributesElm);
|
||||
$this->appendRulesElement($dom, $attributeElm, $this->rules, $this->id);
|
||||
$parent->appendChild($attributeElm);
|
||||
} elseif ("multiComplex" === $this->type) {
|
||||
$attributeElm = $dom->createElement("attribute");
|
||||
$attributeElm->setAttribute("id", $this->id);
|
||||
if ($this->name != "" && !is_null($this->name)) {
|
||||
$attributeElm->setAttribute("name", $this->name);
|
||||
}
|
||||
$attributeElm->setAttribute("type", $this->type);
|
||||
$attributeElm->setAttribute("valueType", "object");
|
||||
|
||||
if (is_array($this->values)) {
|
||||
foreach ($this->values as $complexAttribute) {
|
||||
if ($complexAttribute instanceof XMLAttribute) {
|
||||
$attributesElm = $dom->createElement("attributes");
|
||||
if (is_array($complexAttribute->getValues())) {
|
||||
foreach ($complexAttribute->getValues() as $attribute) {
|
||||
if ($attribute instanceof XMLAttribute) {
|
||||
if (!$this->checkAttributeValueType($attribute->getValueType())) {
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] XMLAttribute属性valueType不正确!");
|
||||
}
|
||||
$attributeElmTmp = $this->appendAttributeValues($dom, $attributesElm, $attribute);
|
||||
$this->appendRulesElement($dom, $attributeElmTmp, $attribute->rules, $attribute->id);
|
||||
$this->appendOptionsElement($dom, $attributeElmTmp, $attribute->options, $attribute->id);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($complexAttribute->getValues())) {//complex类型的values必须是数组 或 空
|
||||
throw new \Exception("id=[" . $complexAttribute->getId() . "] XMLAttribute属性values不合法!");
|
||||
}
|
||||
$attributeElm->appendChild($attributesElm);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($this->values)) {//multiComplex类型的values必须是数组 或 空
|
||||
throw new \Exception("id=[" . $this->id . "] XMLAttribute属性values不合法!");
|
||||
}
|
||||
$parent->appendChild($attributeElm);
|
||||
} else {
|
||||
throw new \Exception("id=[" . $this->id . "] XMLAttribute属性type类型不正确!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function toValueElement($dom, $parent)
|
||||
{
|
||||
$this->checkAttribute();
|
||||
if ("single" === $this->type || "multi" === $this->type) {
|
||||
$this->appendAttributeValues($dom, $parent, $this);
|
||||
} elseif ("complex" === $this->type) {
|
||||
$attributeElm = $dom->createElement("attribute");
|
||||
$attributeElm->setAttribute("id", $this->id);
|
||||
$attributeElm->setAttribute("type", $this->type);
|
||||
if ($this->name != "" && !is_null($this->name)) {
|
||||
$attributeElm->setAttribute("name", $this->name);
|
||||
}
|
||||
if ($this->checkAttributeValueType($this->valueType)) {
|
||||
$attributeElm->setAttribute("valueType", $this->valueType);
|
||||
}
|
||||
|
||||
$attributesElm = $dom->createElement("attributes");
|
||||
if (is_array($this->values)) {
|
||||
foreach ($this->values as $attribute) {
|
||||
if ($attribute instanceof XMLAttribute) {
|
||||
$this->appendAttributeValues($dom, $attributesElm, $attribute);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($this->values)) {//complex类型的values必须是数组 或 空
|
||||
throw new \Exception("id=[" . $this->id . "] XMLAttribute属性values不合法!");
|
||||
}
|
||||
$attributeElm->appendChild($attributesElm);
|
||||
$parent->appendChild($attributeElm);
|
||||
} elseif ("multiComplex" === $this->type) {
|
||||
$attributeElm = $dom->createElement("attribute");
|
||||
$attributeElm->setAttribute("id", $this->id);
|
||||
if ($this->name != "" && !is_null($this->name)) {
|
||||
$attributeElm->setAttribute("name", $this->name);
|
||||
}
|
||||
$attributeElm->setAttribute("type", $this->type);
|
||||
$attributeElm->setAttribute("valueType", "object");
|
||||
|
||||
if (is_array($this->values)) {
|
||||
foreach ($this->values as $complexAttribute) {
|
||||
if ($complexAttribute instanceof XMLAttribute) {
|
||||
$attributesElm = $dom->createElement("attributes");
|
||||
if (is_array($complexAttribute->getValues())) {
|
||||
foreach ($complexAttribute->getValues() as $attribute) {
|
||||
if ($attribute instanceof XMLAttribute) {
|
||||
if (!$this->checkAttributeValueType($attribute->getValueType())) {
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] XMLAttribute属性valueType不正确!");
|
||||
}
|
||||
$this->appendAttributeValues($dom, $attributesElm, $attribute);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($complexAttribute->getValues())) {//complex类型的values必须是数组 或 空
|
||||
throw new \Exception("id=[" . $this->id . "] XMLAttribute属性values不合法!");
|
||||
}
|
||||
$attributeElm->appendChild($attributesElm);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($this->values)) {//multiComplex类型的values必须是数组 或 空
|
||||
throw new \Exception("id=[" . $this->id . "] XMLAttribute属性values不合法!");
|
||||
}
|
||||
$parent->appendChild($attributeElm);
|
||||
} else {
|
||||
throw new \Exception("id=[" . $this->id . "] XMLAttribute属性type类型不正确!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function appendAttributeValues($dom, $parent, $attribute)
|
||||
{
|
||||
$attributeElm = $dom->createElement("attribute");
|
||||
if ($attribute->getId() != "" && !is_null($attribute->getId())) {
|
||||
$attributeElm->setAttribute("id", $attribute->getId());
|
||||
}
|
||||
if ($attribute->getName() != "" && !is_null($attribute->getName())) {
|
||||
$attributeElm->setAttribute("name", $attribute->getName());
|
||||
}
|
||||
if ($attribute->getType() != "" && !is_null($attribute->getType())) {
|
||||
$attributeElm->setAttribute("type", $attribute->getType());
|
||||
}
|
||||
if ($this->checkAttributeValueType($attribute->getValueType())) {
|
||||
$attributeElm->setAttribute("valueType", $attribute->getValueType());
|
||||
}
|
||||
$values = $attribute->getValues();
|
||||
|
||||
if ("single" === $attribute->getType()) {
|
||||
$valueElm = $dom->createElement("value");
|
||||
if (is_string($values)) {
|
||||
$text = $dom->createTextNode($values);
|
||||
$valueElm->appendChild($text);
|
||||
} elseif (!is_null($values)) {//single类型的values必须是字符串 或 空
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] XMLAttribute属性values不合法!");
|
||||
}
|
||||
$attributeElm->appendChild($valueElm);
|
||||
$parent->appendChild($attributeElm);
|
||||
} elseif ("multi" === $attribute->getType()) {
|
||||
$valuesElm = $dom->createElement("values");
|
||||
if (is_array($values)) {
|
||||
foreach ($values as $value) {
|
||||
if (is_string($value) || is_null($value)) {
|
||||
$valueElm = $dom->createElement("value", $value);
|
||||
$valuesElm->appendChild($valueElm);
|
||||
}
|
||||
}
|
||||
} elseif (!empty($values)) {//multi类型的values必须是数组 或 空
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] XMLAttribute属性values不合法!");
|
||||
}
|
||||
$attributeElm->appendChild($valuesElm);
|
||||
$parent->appendChild($attributeElm);
|
||||
} else {
|
||||
throw new \Exception("id=[" . $attribute->getId() . "] XMLAttribute属性type类型不正确!");
|
||||
}
|
||||
return $attributeElm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function appendRulesElement($dom, $parent, $rules, $attributeId)
|
||||
{
|
||||
if (empty($rules)) return;
|
||||
if (!is_array($rules)) {
|
||||
throw new \Exception("id=[" . $attributeId . "] XMLAttribute属性rules不合法!");
|
||||
}
|
||||
$rulesElm = $dom->createElement("rules");
|
||||
foreach ($rules as $rule) {
|
||||
if ($rule instanceof AttributeRule) {
|
||||
$rule->toElement($dom, $rulesElm, $attributeId);
|
||||
}
|
||||
}
|
||||
$parent->appendChild($rulesElm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function appendOptionsElement($dom, $parent, $options, $attributeId)
|
||||
{
|
||||
if (empty($options)) return;
|
||||
if (!is_array($options)) {
|
||||
throw new \Exception("id=[" . $attributeId . "] XMLAttribute属性options不合法!");
|
||||
}
|
||||
$optionsElm = $dom->createElement("options");
|
||||
foreach ($options as $option) {
|
||||
if ($option instanceof Option) {
|
||||
$option->toElement($dom, $optionsElm, $attributeId);
|
||||
}
|
||||
}
|
||||
$parent->appendChild($optionsElm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function checkAttribute()
|
||||
{
|
||||
if (empty($this->id) && $this->id != '0') {
|
||||
throw new \Exception("XMLAttribute属性缺少id!");
|
||||
}
|
||||
if (empty($this->type) && $this->type != '0') {
|
||||
throw new \Exception("id=[" . $this->id . "] XMLAttribute属性缺少type!");
|
||||
}
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function getValueType()
|
||||
{
|
||||
return $this->valueType;
|
||||
}
|
||||
|
||||
public function setValueType($valueType)
|
||||
{
|
||||
$this->valueType = $valueType;
|
||||
}
|
||||
|
||||
public function getRules()
|
||||
{
|
||||
return $this->rules;
|
||||
}
|
||||
|
||||
public function setRules($rules)
|
||||
{
|
||||
$this->rules = $rules;
|
||||
}
|
||||
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function setOptions($options)
|
||||
{
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
public function getValues()
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
public function setValues($values)
|
||||
{
|
||||
$this->values = $values;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user