代码初始化
This commit is contained in:
1
addons/epay/.addonrc
Normal file
1
addons/epay/.addonrc
Normal file
@@ -0,0 +1 @@
|
||||
{"files":["application\/admin\/controller\/Epay.php","public\/assets\/addons\/epay\/less\/common.less","public\/assets\/addons\/epay\/js\/jquery.qrcode.min.js","public\/assets\/addons\/epay\/js\/common.js","public\/assets\/addons\/epay\/css\/common.css","public\/assets\/addons\/epay\/images\/paid.png","public\/assets\/addons\/epay\/images\/scan.png","public\/assets\/addons\/epay\/images\/logo-alipay.png","public\/assets\/addons\/epay\/images\/logo-wechat.png","public\/assets\/addons\/epay\/images\/screenshot-alipay.png","public\/assets\/addons\/epay\/images\/alipay.png","public\/assets\/addons\/epay\/images\/screenshot-wechat.png","public\/assets\/addons\/epay\/images\/wechat.png","public\/assets\/addons\/epay\/images\/expired.png"],"license":"regular","licenseto":"101612","licensekey":"g5nZMF4RcJTD3I2d idWWgXE4jbNMVib2T4zioQ==","domains":["45.221"],"licensecodes":[],"validations":["01aa56d41a1a59da181975a3a6c82078"]}
|
||||
100
addons/epay/Epay.php
Normal file
100
addons/epay/Epay.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay;
|
||||
|
||||
use addons\epay\library\Service;
|
||||
use think\Addons;
|
||||
use think\Config;
|
||||
use think\Loader;
|
||||
|
||||
/**
|
||||
* 微信支付宝整合插件
|
||||
*/
|
||||
class Epay extends Addons
|
||||
{
|
||||
|
||||
/**
|
||||
* 插件安装方法
|
||||
* @return bool
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件卸载方法
|
||||
* @return bool
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件启用方法
|
||||
* @return bool
|
||||
*/
|
||||
public function enable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件禁用方法
|
||||
* @return bool
|
||||
*/
|
||||
public function disable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 支持自定义加载
|
||||
public function epayConfigInit()
|
||||
{
|
||||
$this->actionBegin();
|
||||
}
|
||||
|
||||
// 插件方法加载开始
|
||||
public function addonActionBegin()
|
||||
{
|
||||
$this->actionBegin();
|
||||
}
|
||||
|
||||
// 模块控制器方法加载开始
|
||||
public function actionBegin()
|
||||
{
|
||||
//添加命名空间
|
||||
if (!class_exists('\Yansongda\Pay\Pay')) {
|
||||
|
||||
//SDK版本
|
||||
$version = Service::getSdkVersion();
|
||||
|
||||
$libraryDir = ADDON_PATH . 'epay' . DS . 'library' . DS;
|
||||
Loader::addNamespace('Yansongda\Pay', $libraryDir . $version . DS . 'Yansongda' . DS . 'Pay' . DS);
|
||||
|
||||
$checkArr = [
|
||||
'\Hyperf\Context\Context' => 'context',
|
||||
'\Hyperf\Contract\Castable' => 'contract',
|
||||
'\Hyperf\Engine\Constant' => 'engine',
|
||||
'\Hyperf\Macroable\Macroable' => 'macroable',
|
||||
'\Hyperf\Pimple\Container' => 'pimple',
|
||||
'\Hyperf\Utils\Arr' => 'utils',
|
||||
];
|
||||
foreach ($checkArr as $index => $item) {
|
||||
if (!class_exists($index)) {
|
||||
Loader::addNamespace(substr($index, 1, strrpos($index, '\\') - 1), $libraryDir . 'hyperf' . DS . $item . DS . 'src' . DS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists('\Yansongda\Supports\Logger')) {
|
||||
Loader::addNamespace('Yansongda\Supports', $libraryDir . $version . DS . 'Yansongda' . DS . 'Supports' . DS);
|
||||
}
|
||||
|
||||
// V3需载入辅助函数
|
||||
if ($version == Service::SDK_VERSION_V3) {
|
||||
require_once $libraryDir . $version . DS . 'Yansongda' . DS . 'Pay' . DS . 'Functions.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
0
addons/epay/certs/alipayRootCert.crt
Normal file
0
addons/epay/certs/alipayRootCert.crt
Normal file
450
addons/epay/config.html
Normal file
450
addons/epay/config.html
Normal file
@@ -0,0 +1,450 @@
|
||||
<form id="config-form" class="edit-form form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
||||
|
||||
<div class="panel panel-default panel-intro">
|
||||
<div class="panel-heading">
|
||||
<ul class="nav nav-tabs nav-group">
|
||||
<li class="active"><a href="#wechat" data-toggle="tab">微信支付</a></li>
|
||||
<li><a href="#alipay" data-toggle="tab">支付宝</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div id="myTabContent" class="tab-content">
|
||||
{foreach $addon.config as $item}
|
||||
{if $item.name=='version'}
|
||||
<input type="hidden" value="{$item.value}" name="row[version]"/>
|
||||
|
||||
{elseif $item.name=='wechat'/}
|
||||
<div class="tab-pane fade active in" id="wechat">
|
||||
<table class="table table-striped table-config">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="20%">APP的app_id</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][appid]" value="{$item.value.appid|default=''}" class="form-control" data-rule="" data-tip="APP应用中支付时使用"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>公众号的app_id</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][app_id]" value="{$item.value.app_id|default=''}" class="form-control" data-rule="" data-tip="公众号中支付时使用"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>公众号的app_secret</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][app_secret]" value="{$item.value.app_secret|default=''}" class="form-control" data-rule="" data-tip="公众号中支付时使用"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>小程序的app_id</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][miniapp_id]" value="{$item.value.miniapp_id|default=''}" class="form-control" data-rule="" data-tip="仅在小程序支付时使用"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>微信支付商户号</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][mch_id]" value="{$item.value.mch_id|default=''}" class="form-control" data-rule="" data-tip=""/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>微信支付商户API密钥V2</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][key]" value="{$item.value.key|default=''}" class="form-control" data-rule="" data-tip=""/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>微信支付商户API密钥V3</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][key_v3]" value="{$item.value.key_v3|default=''}" class="form-control" data-rule="" data-tip=""/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>支付模式</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
{:Form::radios('row[wechat][mode]',['normal'=>'正式环境','dev'=>'沙箱环境','service'=>'服务商模式'],$item.value.mode??'normal')}
|
||||
<div style="margin-top:5px;" data-type="dev" class="text-muted {if ($item.value.mode??'')!=='dev'}hidden{/if}">
|
||||
<i class="fa fa-info-circle"></i> 沙箱环境:<a href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_1&index=2" target="_blank">微信支付验收指引</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-type="service" class="{:$item.value.mode!='service'?'hidden':''}">
|
||||
<td>子商户商户号ID</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][sub_mch_id]" value="{$item.value.sub_mch_id|default=''}" class="form-control" data-rule="" data-tip="如果未用到子商户,请勿填写"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-type="service" class="{:$item.value.mode!='service'?'hidden':''}">
|
||||
<td>子商户APP的app_id</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][sub_appid]" value="{$item.value.sub_appid|default=''}" class="form-control" data-rule="" data-tip="如果未用到子商户,请勿填写"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-type="service" class="{:$item.value.mode!='service'?'hidden':''}">
|
||||
<td>子商户公众号的app_id</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][sub_app_id]" value="{$item.value.sub_app_id|default=''}" class="form-control" data-rule="" data-tip="如果未用到子商户,请勿填写"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-type="service" class="{:$item.value.mode!='service'?'hidden':''}">
|
||||
<td>子商户小程序的app_id</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][sub_miniapp_id]" value="{$item.value.sub_miniapp_id|default=''}" class="form-control" data-rule="" data-tip="如果未用到子商户,请勿填写"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>回调通知地址</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[wechat][notify_url]" value="{$item.value.notify_url|default=''}" class="form-control" data-rule="" data-tip="请勿随意修改,实际以逻辑代码中请求的为准"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>微信支付API证书cert</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<div class="input-group">
|
||||
<input id="c-cert_client" class="form-control" size="50" name="row[wechat][cert_client]" type="text" value="{$item.value.cert_client|htmlentities}" data-tip="可选, 仅在退款、红包等情况时需要用到">
|
||||
<div class="input-group-addon no-border no-padding">
|
||||
<span><button type="button" id="faupload-cert_client" class="btn btn-danger faupload" data-url="epay/upload" data-multipart='{"certname":"cert_client"}' data-mimetype="pem" data-input-id="c-cert_client" data-multiple="false"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||
</div>
|
||||
<span class="msg-box n-right" for="c-cert_client"></span>
|
||||
</div>
|
||||
<div style="margin-top:5px;"><a href="https://pay.weixin.qq.com" target="_blank"><i class="fa fa-question-circle"></i> 如何获取微信支付API证书?</a></div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>微信支付API证书key</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<div class="input-group">
|
||||
<input id="c-cert_key" class="form-control" size="50" name="row[wechat][cert_key]" type="text" value="{$item.value.cert_key|htmlentities}" data-tip="可选, 仅在退款、红包等情况时需要用到">
|
||||
<div class="input-group-addon no-border no-padding">
|
||||
<span><button type="button" id="faupload-cert_key" class="btn btn-danger faupload" data-url="epay/upload" data-multipart='{"certname":"cert_key"}' data-mimetype="pem" data-input-id="c-cert_key" data-multiple="false"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||
</div>
|
||||
<span class="msg-box n-right" for="c-cert_key"></span>
|
||||
</div>
|
||||
<div style="margin-top:5px;"><a href="https://pay.weixin.qq.com" target="_blank"><i class="fa fa-question-circle"></i> 如何获取微信支付API证书?</a></div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>记录日志</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
{:Form::radios('row[wechat][log]',['1'=>'开启','0'=>'关闭'],$item.value.log)}
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{elseif $item.name=='alipay'}
|
||||
<div class="tab-pane fade" id="alipay">
|
||||
<table class="table table-striped table-config">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>支付模式</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-xs-12">
|
||||
{:Form::radios('row[alipay][mode]',['normal'=>'正式环境','dev'=>'沙箱环境', 'service'=>'服务商模式'],$item.value.mode??'normal')}
|
||||
|
||||
<div style="margin-top:5px;" data-mode="dev" class="text-muted {if ($item.value.mode??'')!=='dev'}hidden{/if}">
|
||||
<i class="fa fa-info-circle"></i> 如果使用沙箱环境,务必使用沙箱的app_id和沙箱配置,以及使用沙箱账号进行测试。<br>
|
||||
沙箱环境:<a href="https://openhome.alipay.com/develop/sandbox/app" target="_blank">https://openhome.alipay.com/develop/sandbox/app</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="text-muted {if ($item.value.mode??'')!=='service'}hidden{/if}" data-mode="service">
|
||||
<td width="20%">服务商ID(pid)</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[alipay][pid]" value="{$item.value.pid|default=''}" class="form-control" data-rule="" data-tip=""/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20%">应用ID(app_id)</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[alipay][app_id]" value="{$item.value.app_id|default=''}" class="form-control" data-rule="" data-tip=""/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>回调通知地址</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[alipay][notify_url]" value="{$item.value.notify_url|default=''}" class="form-control" data-rule="" data-tip="请勿随意修改,实际以逻辑代码中请求的为准"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>支付跳转地址</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[alipay][return_url]" value="{$item.value.return_url|default=''}" class="form-control" data-rule="" data-tip="请勿随意修改,实际以逻辑代码中请求的为准"/>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>应用私钥(private_key)</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<input type="text" name="row[alipay][private_key]" value="{$item.value.private_key|default=''}" class="form-control" data-rule=""/>
|
||||
<div style="margin-top:5px;"><a href="https://opensupport.alipay.com/support/helpcenter/207/201602469554" target="_blank"><i class="fa fa-question-circle"></i> 如何获取应用私钥?</a></div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>签名方式</td>
|
||||
<td>
|
||||
<div>
|
||||
<div class="radio">
|
||||
<label for="row[alipay][signtype]-publickey"><input id="row[alipay][signtype]-publickey" name="row[alipay][signtype]" {if isset($item.value.signtype)&&$item.value.signtype=='publickey'}checked{/if} type="radio" value="publickey"> 普通公钥</label>
|
||||
<label for="row[alipay][signtype]-cert"><input id="row[alipay][signtype]-cert" {if isset($item.value.signtype)&&$item.value.signtype=='cert'}checked{/if} name="row[alipay][signtype]" type="radio" value="cert"> 公钥证书</label>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin:5px 0;" class="text-muted">
|
||||
<i class="fa fa-info-circle"></i> 如果要使用转账、提现功能,则必须使用公钥证书
|
||||
</div>
|
||||
<div data-signtype="publickey" class="{if ($item.value.signtype??'')==='cert'}hidden{/if}">
|
||||
<a href="https://opensupport.alipay.com/support/FAQ/65b9c843a8e10e054512d07dprod" target="_blank"><i class="fa fa-info-circle"></i> 如何生成支付宝公钥、应用私钥?</a>
|
||||
</div>
|
||||
<div data-signtype="cert" class="{if ($item.value.signtype??'')==='publickey'}hidden{/if}">
|
||||
<a href="https://opensupport.alipay.com/support/FAQ/6718ab4563fae8044fe13dc7prod" target="_blank"><i class="fa fa-info-circle"></i> 支付宝公钥证书、应用公钥证书、支付宝根证书?</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span data-signtype="publickey" class="{if ($item.value.signtype??'')==='cert'}hidden{/if}">支付宝公钥</span>
|
||||
<span data-signtype="cert" class="{if ($item.value.signtype??'')==='publickey' || ($item.value.signtype??'')==''}hidden{/if}">支付宝公钥证书路径</span>
|
||||
(alipay_public_key)
|
||||
</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<div class="input-group">
|
||||
<input id="c-ali_public_key" class="form-control" size="50" name="row[alipay][ali_public_key]" type="text" value="{$item.value.ali_public_key|default=''|htmlentities}" placeholder="普通公钥请直接粘贴,公钥证书请点击右侧的上传">
|
||||
<div class="input-group-addon no-border no-padding {if ($item.value.signtype??'')==='publickey' || ($item.value.signtype??'')==''}hidden{/if}" data-signtype="cert">
|
||||
<span><button type="button" id="faupload-ali_public_key" class="btn btn-danger faupload" data-url="epay/upload" data-multipart='{"certname":"ali_public_key"}' data-mimetype="crt" data-input-id="c-ali_public_key" data-multiple="false"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||
</div>
|
||||
<span class="msg-box n-right" for="c-ali_public_key"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="{if ($item.value.signtype??'')==='publickey' || ($item.value.signtype??'')==''}hidden{/if}" data-signtype="cert">
|
||||
<td>
|
||||
<span data-signtype="publickey" class="{if ($item.value.signtype??'')==='cert'}hidden{/if}">应用公钥</span>
|
||||
<span data-signtype="cert" class="{if ($item.value.signtype??'')==='publickey' || ($item.value.signtype??'')==''}hidden{/if}">应用公钥证书路径</span>
|
||||
(app_cert_public_key)
|
||||
</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<div class="input-group">
|
||||
<input id="c-app_cert_public_key" class="form-control" size="50" name="row[alipay][app_cert_public_key]" type="text" value="{$item.value.app_cert_public_key|default=''|htmlentities}">
|
||||
<div class="input-group-addon no-border no-padding {if ($item.value.signtype??'')==='publickey' || ($item.value.signtype??'')==''}hidden{/if}" data-signtype="cert">
|
||||
<span><button type="button" id="faupload-app_cert_public_key" class="btn btn-danger faupload" data-url="epay/upload" data-multipart='{"certname":"app_cert_public_key"}' data-mimetype="crt" data-input-id="c-app_cert_public_key" data-multiple="false"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||
</div>
|
||||
<span class="msg-box n-right" for="c-app_cert_public_key"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="{if ($item.value.signtype??'')==='publickey' || ($item.value.signtype??'')==''}hidden{/if}" data-signtype="cert">
|
||||
<td>支付宝根证书路径(alipay_root_cert)</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
<div class="input-group">
|
||||
<input id="c-alipay_root_cert" class="form-control" size="50" name="row[alipay][alipay_root_cert]" type="text" value="{$item.value.alipay_root_cert|default=''|htmlentities}">
|
||||
<div class="input-group-addon no-border no-padding">
|
||||
<span><button type="button" id="faupload-alipay_root_cert" class="btn btn-danger faupload" data-url="epay/upload" data-multipart='{"certname":"alipay_root_cert"}' data-mimetype="crt" data-input-id="c-alipay_root_cert" data-multiple="false"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||
</div>
|
||||
<span class="msg-box n-right" for="c-alipay_root_cert"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>记录日志</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
{:Form::radios('row[alipay][log]',['1'=>'开启','0'=>'关闭'],$item.value.log)}
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>PC端使用扫码支付</td>
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-xs-12">
|
||||
{:Form::radios('row[alipay][scanpay]',['1'=>'开启','0'=>'关闭'],$item.value.scanpay??0)}
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
{/foreach}
|
||||
<div class="form-group layer-footer">
|
||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
|
||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
require.callback = function () {
|
||||
define('backend/addon', ['backend', 'form'], function (Backend, Form) {
|
||||
var Controller = {
|
||||
config: function () {
|
||||
$(document).on("click", ".nav-group li a[data-toggle='tab']", function () {
|
||||
if ($(this).attr("href") === "#all") {
|
||||
$(".tab-pane").addClass("active in");
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
$(document).on("click", "input[name='row[wechat][mode]']", function () {
|
||||
$("#wechat [data-type]").addClass("hidden");
|
||||
$("#wechat [data-type='" + $(this).val() + "']").removeClass("hidden");
|
||||
});
|
||||
$(document).on("click", "input[name='row[alipay][mode]']", function () {
|
||||
$("#alipay [data-mode]").addClass("hidden");
|
||||
$("#alipay [data-mode='" + $(this).val() + "']").removeClass("hidden");
|
||||
});
|
||||
$(document).on("click", "input[name='row[alipay][signtype]']", function () {
|
||||
let value = $(this).val();
|
||||
$("#alipay [data-signtype]").addClass("hidden");
|
||||
$("#alipay [data-signtype='" + value + "']").removeClass("hidden");
|
||||
});
|
||||
|
||||
Form.api.bindevent($("form[role=form]"), undefined, undefined, function () {
|
||||
let value = $("input[name='row[alipay][signtype]']:checked").val();
|
||||
// 如果选择了普通公钥,则需要清空未使用的应用公钥证书路径值和支付宝根证书路径值
|
||||
if (value === 'publickey') {
|
||||
$("#c-app_cert_public_key,#c-alipay_root_cert").val('');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
return Controller;
|
||||
});
|
||||
};
|
||||
</script>
|
||||
70
addons/epay/config.php
Normal file
70
addons/epay/config.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
'name' => 'version',
|
||||
'title' => 'API版本(请勿修改该值)',
|
||||
'type' => 'radio',
|
||||
'content' => [],
|
||||
'value' => 'v2',
|
||||
'rule' => '',
|
||||
'msg' => '',
|
||||
'tip' => 'V2版本只支持微信支付V2密钥,V3版本只支持微信支付V3密钥,请勿修改该值!!!',
|
||||
'ok' => '',
|
||||
'extend' => '',
|
||||
],
|
||||
[
|
||||
'name' => 'wechat',
|
||||
'title' => '微信',
|
||||
'type' => 'array',
|
||||
'content' => [],
|
||||
'value' => [
|
||||
'appid' => '',
|
||||
'app_id' => '',
|
||||
'app_secret' => '',
|
||||
'miniapp_id' => '',
|
||||
'mch_id' => '',
|
||||
'key' => '',
|
||||
'key_v3' => '',
|
||||
'mode' => 'normal',
|
||||
'sub_mch_id' => '',
|
||||
'sub_appid' => '',
|
||||
'sub_app_id' => '',
|
||||
'sub_miniapp_id' => '',
|
||||
'notify_url' => '',
|
||||
'cert_client' => '/addons/epay/certs/apiclient_cert.pem',
|
||||
'cert_key' => '/addons/epay/certs/apiclient_key.pem',
|
||||
'log' => '1',
|
||||
],
|
||||
'rule' => 'required',
|
||||
'msg' => '',
|
||||
'tip' => '微信参数配置',
|
||||
'ok' => '',
|
||||
'extend' => '',
|
||||
],
|
||||
[
|
||||
'name' => 'alipay',
|
||||
'title' => '支付宝',
|
||||
'type' => 'array',
|
||||
'content' => [],
|
||||
'value' => [
|
||||
'app_id' => '',
|
||||
'mode' => 'normal',
|
||||
'notify_url' => '/addons/epay/api/notifyx/type/alipay',
|
||||
'return_url' => '/addons/epay/api/returnx/type/alipay',
|
||||
'private_key' => '',
|
||||
'signtype' => 'cert',
|
||||
'pid' => '',
|
||||
'ali_public_key' => '',
|
||||
'app_cert_public_key' => '',
|
||||
'alipay_root_cert' => '',
|
||||
'log' => '1',
|
||||
'scanpay' => '0',
|
||||
],
|
||||
'rule' => 'required',
|
||||
'msg' => '',
|
||||
'tip' => '支付宝参数配置',
|
||||
'ok' => '',
|
||||
'extend' => '',
|
||||
]
|
||||
];
|
||||
234
addons/epay/controller/Api.php
Normal file
234
addons/epay/controller/Api.php
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay\controller;
|
||||
|
||||
use addons\epay\library\Service;
|
||||
use addons\epay\library\Wechat;
|
||||
use addons\third\model\Third;
|
||||
use app\common\library\Auth;
|
||||
use Exception;
|
||||
use think\addons\Controller;
|
||||
use think\Response;
|
||||
use think\Session;
|
||||
use Yansongda\Pay\Exceptions\GatewayException;
|
||||
use Yansongda\Pay\Pay;
|
||||
|
||||
/**
|
||||
* API接口控制器
|
||||
*
|
||||
* @package addons\epay\controller
|
||||
*/
|
||||
class Api extends Controller
|
||||
{
|
||||
|
||||
protected $layout = 'default';
|
||||
protected $config = [];
|
||||
|
||||
/**
|
||||
* 默认方法
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 外部提交
|
||||
*/
|
||||
public function submit()
|
||||
{
|
||||
$this->request->filter('trim');
|
||||
$out_trade_no = $this->request->request("out_trade_no");
|
||||
$title = $this->request->request("title");
|
||||
$amount = $this->request->request('amount');
|
||||
$type = $this->request->request('type', $this->request->request('paytype'));
|
||||
$method = $this->request->request('method', 'web');
|
||||
$openid = $this->request->request('openid', '');
|
||||
$auth_code = $this->request->request('auth_code', '');
|
||||
$notifyurl = $this->request->request('notifyurl', '');
|
||||
$returnurl = $this->request->request('returnurl', '');
|
||||
|
||||
if (!$amount || $amount < 0) {
|
||||
$this->error("支付金额必须大于0");
|
||||
}
|
||||
|
||||
if (!$type || !in_array($type, ['alipay', 'wechat'])) {
|
||||
$this->error("支付类型错误");
|
||||
}
|
||||
|
||||
$params = [
|
||||
'type' => $type,
|
||||
'out_trade_no' => $out_trade_no,
|
||||
'title' => $title,
|
||||
'amount' => $amount,
|
||||
'method' => $method,
|
||||
'openid' => $openid,
|
||||
'auth_code' => $auth_code,
|
||||
'notifyurl' => $notifyurl,
|
||||
'returnurl' => $returnurl,
|
||||
];
|
||||
return Service::submitOrder($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付(公众号支付&PC扫码支付)
|
||||
*/
|
||||
public function wechat()
|
||||
{
|
||||
$config = Service::getConfig('wechat');
|
||||
|
||||
$isWechat = stripos($this->request->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;
|
||||
$isMobile = $this->request->isMobile();
|
||||
$this->view->assign("isWechat", $isWechat);
|
||||
$this->view->assign("isMobile", $isMobile);
|
||||
|
||||
//发起PC支付(Scan支付)(PC扫码模式)
|
||||
if ($this->request->isAjax()) {
|
||||
$pay = Pay::wechat($config);
|
||||
$orderid = $this->request->post("orderid");
|
||||
try {
|
||||
$result = Service::isVersionV3() ? $pay->find(['out_trade_no' => $orderid]) : $pay->find($orderid, 'scan');
|
||||
$this->success("", "", ['status' => $result['trade_state'] ?? 'NOTPAY']);
|
||||
} catch (GatewayException $e) {
|
||||
$this->error("查询失败(1001)");
|
||||
}
|
||||
}
|
||||
|
||||
$orderData = Session::get("wechatorderdata");
|
||||
if (!$orderData) {
|
||||
$this->error("请求参数错误");
|
||||
}
|
||||
if ($isWechat && $isMobile) {
|
||||
//发起公众号(jsapi支付),openid必须
|
||||
|
||||
//如果没有openid,则自动去获取openid
|
||||
if (!isset($orderData['openid']) || !$orderData['openid']) {
|
||||
$orderData['openid'] = Service::getOpenid();
|
||||
}
|
||||
|
||||
$orderData['method'] = 'mp';
|
||||
$type = 'jsapi';
|
||||
$payData = Service::submitOrder($orderData);
|
||||
if (!isset($payData['paySign'])) {
|
||||
$this->error("创建订单失败,请返回重试", "");
|
||||
}
|
||||
} else {
|
||||
$orderData['method'] = 'scan';
|
||||
$type = 'pc';
|
||||
$payData = Service::submitOrder($orderData);
|
||||
if (!isset($payData['code_url'])) {
|
||||
$this->error("创建订单失败,请返回重试", "");
|
||||
}
|
||||
}
|
||||
$this->view->assign("orderData", $orderData);
|
||||
$this->view->assign("payData", $payData);
|
||||
$this->view->assign("type", $type);
|
||||
|
||||
$this->view->assign("title", "微信支付");
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝支付(PC扫码支付)
|
||||
*/
|
||||
public function alipay()
|
||||
{
|
||||
$config = Service::getConfig('alipay');
|
||||
|
||||
$isWechat = stripos($this->request->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;
|
||||
$isMobile = $this->request->isMobile();
|
||||
$this->view->assign("isWechat", $isWechat);
|
||||
$this->view->assign("isMobile", $isMobile);
|
||||
|
||||
if ($this->request->isAjax()) {
|
||||
$orderid = $this->request->post("orderid");
|
||||
$pay = Pay::alipay($config);
|
||||
try {
|
||||
$result = $pay->find(['out_trade_no' => $orderid]);
|
||||
if ($result['code'] == '10000' && $result['trade_status'] == 'TRADE_SUCCESS') {
|
||||
$this->success("", "", ['status' => $result['trade_status']]);
|
||||
} else {
|
||||
$this->error("查询失败");
|
||||
}
|
||||
} catch (GatewayException $e) {
|
||||
$this->error("查询失败(1001)");
|
||||
}
|
||||
}
|
||||
|
||||
//发起PC支付(Scan支付)(PC扫码模式)
|
||||
$orderData = Session::get("alipayorderdata");
|
||||
if (!$orderData) {
|
||||
$this->error("请求参数错误");
|
||||
}
|
||||
|
||||
$orderData['method'] = 'scan';
|
||||
$payData = Service::submitOrder($orderData);
|
||||
if (!isset($payData['qr_code'])) {
|
||||
$this->error("创建订单失败,请返回重试");
|
||||
}
|
||||
|
||||
$type = 'pc';
|
||||
$this->view->assign("orderData", $orderData);
|
||||
$this->view->assign("payData", $payData);
|
||||
$this->view->assign("type", $type);
|
||||
$this->view->assign("title", "支付宝支付");
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付成功回调
|
||||
*/
|
||||
public function notifyx()
|
||||
{
|
||||
$paytype = $this->request->param('paytype');
|
||||
$pay = Service::checkNotify($paytype);
|
||||
if (!$pay) {
|
||||
return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
|
||||
// 获取回调数据,V3和V2的回调接收不同
|
||||
$data = Service::isVersionV3() ? $pay->callback() : $pay->verify();
|
||||
|
||||
try {
|
||||
//微信支付V3返回和V2不同
|
||||
if (Service::isVersionV3() && $paytype === 'wechat') {
|
||||
$data = $data['resource']['ciphertext'];
|
||||
$data['total_fee'] = $data['amount']['total'];
|
||||
}
|
||||
|
||||
\think\Log::record($data);
|
||||
//获取支付金额、订单号
|
||||
$payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
|
||||
$out_trade_no = $data['out_trade_no'];
|
||||
|
||||
\think\Log::record("回调成功,订单号:{$out_trade_no},金额:{$payamount}");
|
||||
|
||||
//你可以在此编写订单逻辑
|
||||
} catch (Exception $e) {
|
||||
\think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
|
||||
}
|
||||
|
||||
//下面这句必须要执行,且在此之前不能有任何输出
|
||||
if (Service::isVersionV3()) {
|
||||
return $pay->success()->getBody()->getContents();
|
||||
} else {
|
||||
return $pay->success()->send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付成功返回
|
||||
*/
|
||||
public function returnx()
|
||||
{
|
||||
$paytype = $this->request->param('paytype');
|
||||
if (Service::checkReturn($paytype)) {
|
||||
echo '签名错误';
|
||||
return;
|
||||
}
|
||||
|
||||
//你可以在这里定义你的提示信息,但切记不可在此编写逻辑
|
||||
$this->success("恭喜你!支付成功!", addon_url("epay/index/index"));
|
||||
}
|
||||
|
||||
}
|
||||
131
addons/epay/controller/Index.php
Normal file
131
addons/epay/controller/Index.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay\controller;
|
||||
|
||||
use addons\epay\library\Service;
|
||||
use fast\Random;
|
||||
use think\addons\Controller;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* 微信支付宝整合插件首页
|
||||
*
|
||||
* 此控制器仅用于开发展示说明和测试,请自行添加一个新的控制器进行处理返回和回调事件,同时删除此控制器文件
|
||||
*
|
||||
* Class Index
|
||||
* @package addons\epay\controller
|
||||
*/
|
||||
class Index extends Controller
|
||||
{
|
||||
protected $layout = 'default';
|
||||
|
||||
protected $config = [];
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
if (!config("app_debug")) {
|
||||
$this->error("仅在开发环境下查看");
|
||||
}
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->view->assign("title", "微信支付宝整合");
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 体验,仅供开发测试
|
||||
*/
|
||||
public function experience()
|
||||
{
|
||||
$amount = $this->request->post('amount');
|
||||
$type = $this->request->post('type');
|
||||
$method = $this->request->post('method');
|
||||
$openid = $this->request->post('openid', "");
|
||||
|
||||
if (!$amount || $amount < 0) {
|
||||
$this->error("支付金额必须大于0");
|
||||
}
|
||||
|
||||
if (!$type || !in_array($type, ['alipay', 'wechat'])) {
|
||||
$this->error("支付类型不能为空");
|
||||
}
|
||||
|
||||
if (in_array($method, ['miniapp', 'mp']) && !$openid) {
|
||||
$this->error("openid不能为空");
|
||||
}
|
||||
|
||||
//订单号
|
||||
$out_trade_no = date("YmdHis") . mt_rand(100000, 999999);
|
||||
|
||||
//订单标题
|
||||
$title = '测试订单';
|
||||
|
||||
//回调链接
|
||||
$notifyurl = $this->request->root(true) . '/addons/epay/index/notifyx/paytype/' . $type;
|
||||
$returnurl = $this->request->root(true) . '/addons/epay/index/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;
|
||||
|
||||
$response = Service::submitOrder($amount, $out_trade_no, $type, $title, $notifyurl, $returnurl, $method, $openid);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付成功,仅供开发测试
|
||||
*/
|
||||
public function notifyx()
|
||||
{
|
||||
$paytype = $this->request->param('paytype');
|
||||
$pay = Service::checkNotify($paytype);
|
||||
if (!$pay) {
|
||||
return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
|
||||
}
|
||||
|
||||
// 获取回调数据,V3和V2的回调接收不同
|
||||
$data = Service::isVersionV3() ? $pay->callback() : $pay->verify();
|
||||
|
||||
try {
|
||||
//微信支付V3返回和V2不同
|
||||
if (Service::isVersionV3() && $paytype === 'wechat') {
|
||||
$data = $data['resource']['ciphertext'];
|
||||
$data['total_fee'] = $data['amount']['total'];
|
||||
}
|
||||
|
||||
\think\Log::record($data);
|
||||
//获取支付金额、订单号
|
||||
$payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
|
||||
$out_trade_no = $data['out_trade_no'];
|
||||
|
||||
\think\Log::record("回调成功,订单号:{$out_trade_no},金额:{$payamount}");
|
||||
|
||||
//你可以在此编写订单逻辑
|
||||
} catch (Exception $e) {
|
||||
\think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
|
||||
}
|
||||
|
||||
//下面这句必须要执行,且在此之前不能有任何输出
|
||||
if (Service::isVersionV3()) {
|
||||
return $pay->success()->getBody()->getContents();
|
||||
} else {
|
||||
return $pay->success()->send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付返回,仅供开发测试
|
||||
*/
|
||||
public function returnx()
|
||||
{
|
||||
$paytype = $this->request->param('paytype');
|
||||
$out_trade_no = $this->request->param('out_trade_no');
|
||||
$pay = Service::checkReturn($paytype);
|
||||
if (!$pay) {
|
||||
$this->error('签名错误', '');
|
||||
}
|
||||
|
||||
//你可以在这里定义你的提示信息,但切记不可在此编写逻辑
|
||||
$this->success("请返回网站查看支付结果", addon_url("epay/index/index"));
|
||||
}
|
||||
}
|
||||
10
addons/epay/info.ini
Normal file
10
addons/epay/info.ini
Normal file
@@ -0,0 +1,10 @@
|
||||
name = epay
|
||||
title = 微信支付宝整合
|
||||
intro = 可用于快速整合企业微信、支付宝支付功能
|
||||
author = FastAdmin
|
||||
website = https://www.fastadmin.net
|
||||
version = 1.3.9
|
||||
state = 1
|
||||
url = /addons/epay
|
||||
license = regular
|
||||
licenseto = 101612
|
||||
18
addons/epay/library/Collection.php
Normal file
18
addons/epay/library/Collection.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay\library;
|
||||
|
||||
class Collection extends \Yansongda\Supports\Collection
|
||||
{
|
||||
|
||||
/**
|
||||
* 创建 Collection 实例
|
||||
* @access public
|
||||
* @param array $items 数据
|
||||
* @return static
|
||||
*/
|
||||
public static function make($items = [])
|
||||
{
|
||||
return new static($items);
|
||||
}
|
||||
}
|
||||
16
addons/epay/library/OrderException.php
Normal file
16
addons/epay/library/OrderException.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay\library;
|
||||
|
||||
use think\Exception;
|
||||
|
||||
class OrderException extends Exception
|
||||
{
|
||||
public function __construct($message = "", $code = 0, $data = [])
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
}
|
||||
58
addons/epay/library/RedirectResponse.php
Normal file
58
addons/epay/library/RedirectResponse.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay\library;
|
||||
|
||||
class RedirectResponse extends \Symfony\Component\HttpFoundation\RedirectResponse implements \JsonSerializable, \Serializable
|
||||
{
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getContent();
|
||||
}
|
||||
|
||||
public function setTargetUrl($url)
|
||||
{
|
||||
if ('' === ($url ?? '')) {
|
||||
throw new \InvalidArgumentException('无法跳转到空页面');
|
||||
}
|
||||
|
||||
$this->targetUrl = $url;
|
||||
|
||||
$this->setContent(
|
||||
sprintf('<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="refresh" content="0;url=\'%1$s\'" />
|
||||
|
||||
<title>正在跳转支付 %1$s</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="redirect" style="display:none;">正在跳转支付 <a href="%1$s">%1$s</a></div>
|
||||
<script type="text/javascript">
|
||||
setTimeout(function(){
|
||||
document.getElementById("redirect").style.display = "block";
|
||||
}, 1000);
|
||||
</script>
|
||||
</body>
|
||||
</html>', htmlspecialchars($url, \ENT_QUOTES, 'UTF-8')));
|
||||
|
||||
$this->headers->set('Location', $url);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->getContent();
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return serialize($this->content);
|
||||
}
|
||||
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
return $this->content = unserialize($serialized);
|
||||
}
|
||||
}
|
||||
26
addons/epay/library/Response.php
Normal file
26
addons/epay/library/Response.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay\library;
|
||||
|
||||
class Response extends \Symfony\Component\HttpFoundation\Response implements \JsonSerializable, \Serializable
|
||||
{
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getContent();
|
||||
}
|
||||
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->getContent();
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return serialize($this->content);
|
||||
}
|
||||
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
return $this->content = unserialize($serialized);
|
||||
}
|
||||
}
|
||||
489
addons/epay/library/Service.php
Normal file
489
addons/epay/library/Service.php
Normal file
@@ -0,0 +1,489 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay\library;
|
||||
|
||||
use addons\third\model\Third;
|
||||
use app\common\library\Auth;
|
||||
use Exception;
|
||||
use think\Hook;
|
||||
use think\Session;
|
||||
use Yansongda\Pay\Pay;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
/**
|
||||
* 订单服务类
|
||||
*
|
||||
* @package addons\epay\library
|
||||
*/
|
||||
class Service
|
||||
{
|
||||
|
||||
public const SDK_VERSION_V2 = 'v2';
|
||||
|
||||
public const SDK_VERSION_V3 = 'v3';
|
||||
|
||||
/**
|
||||
* 提交订单
|
||||
* @param array|float $amount 订单金额
|
||||
* @param string $orderid 订单号
|
||||
* @param string $type 支付类型,可选alipay或wechat
|
||||
* @param string $title 订单标题
|
||||
* @param string $notifyurl 通知回调URL
|
||||
* @param string $returnurl 跳转返回URL
|
||||
* @param string $method 支付方法
|
||||
* @param string $openid Openid
|
||||
* @param array $custom 自定义微信支付宝相关配置
|
||||
* @return Response|RedirectResponse|Collection
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function submitOrder($amount, $orderid = null, $type = null, $title = null, $notifyurl = null, $returnurl = null, $method = null, $openid = '', $custom = [])
|
||||
{
|
||||
$version = self::getSdkVersion();
|
||||
$request = request();
|
||||
$addonConfig = get_addon_config('epay');
|
||||
|
||||
if (!is_array($amount)) {
|
||||
$params = [
|
||||
'amount' => $amount,
|
||||
'orderid' => $orderid,
|
||||
'type' => $type,
|
||||
'title' => $title,
|
||||
'notifyurl' => $notifyurl,
|
||||
'returnurl' => $returnurl,
|
||||
'method' => $method,
|
||||
'openid' => $openid,
|
||||
'custom' => $custom,
|
||||
];
|
||||
} else {
|
||||
$params = $amount;
|
||||
}
|
||||
$type = isset($params['type']) && in_array($params['type'], ['alipay', 'wechat']) ? $params['type'] : 'wechat';
|
||||
$method = $params['method'] ?? 'web';
|
||||
$orderid = $params['orderid'] ?? date("YmdHis") . mt_rand(100000, 999999);
|
||||
$amount = $params['amount'] ?? 1;
|
||||
$title = $params['title'] ?? "支付";
|
||||
$auth_code = $params['auth_code'] ?? '';
|
||||
$openid = $params['openid'] ?? '';
|
||||
|
||||
//自定义微信支付宝相关配置
|
||||
$custom = $params['custom'] ?? [];
|
||||
|
||||
//未定义则使用默认回调和跳转
|
||||
$notifyurl = !empty($params['notifyurl']) ? $params['notifyurl'] : $request->root(true) . '/addons/epay/index/notifyx/paytype/' . $type;
|
||||
$returnurl = !empty($params['returnurl']) ? $params['returnurl'] : $request->root(true) . '/addons/epay/index/returnx/paytype/' . $type . '/out_trade_no/' . $orderid;
|
||||
|
||||
$html = '';
|
||||
$config = Service::getConfig($type, array_merge($custom, ['notify_url' => $notifyurl, 'return_url' => $returnurl]));
|
||||
|
||||
//判断是否移动端或微信内浏览器
|
||||
$isMobile = $request->isMobile();
|
||||
$isWechat = strpos($request->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;
|
||||
|
||||
$result = null;
|
||||
if ($type == 'alipay') {
|
||||
//如果是PC支付,判断当前环境,进行跳转
|
||||
if ($method == 'web') {
|
||||
//如果是微信环境或后台配置PC使用扫码支付
|
||||
if ($isWechat || $addonConfig['alipay']['scanpay']) {
|
||||
Session::set("alipayorderdata", $params);
|
||||
$url = addon_url('epay/api/alipay', [], true, true);
|
||||
return new RedirectResponse($url);
|
||||
} elseif ($isMobile) {
|
||||
$method = 'wap';
|
||||
}
|
||||
}
|
||||
|
||||
//创建支付对象
|
||||
$pay = Pay::alipay($config);
|
||||
$params = [
|
||||
'out_trade_no' => $orderid,//你的订单号
|
||||
'total_amount' => $amount,//单位元
|
||||
'subject' => $title,
|
||||
];
|
||||
|
||||
switch ($method) {
|
||||
case 'web':
|
||||
//电脑支付
|
||||
$result = $pay->web($params);
|
||||
break;
|
||||
case 'wap':
|
||||
//手机网页支付
|
||||
$result = $pay->wap($params);
|
||||
break;
|
||||
case 'app':
|
||||
//APP支付
|
||||
$result = $pay->app($params);
|
||||
break;
|
||||
case 'scan':
|
||||
//扫码支付
|
||||
$result = $pay->scan($params);
|
||||
break;
|
||||
case 'pos':
|
||||
//刷卡支付必须要有auth_code
|
||||
$params['auth_code'] = $auth_code;
|
||||
$result = $pay->pos($params);
|
||||
break;
|
||||
case 'mini':
|
||||
case 'miniapp':
|
||||
//小程序支付,直接返回字符串
|
||||
//小程序支付必须要有buyer_id或buyer_open_id
|
||||
if (is_numeric($openid) && strlen($openid) === 16) {
|
||||
$params['buyer_id'] = $openid;
|
||||
} else {
|
||||
$params['buyer_open_id'] = $openid;
|
||||
}
|
||||
$result = $pay->mini($params);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
} else {
|
||||
//如果是PC支付,判断当前环境,进行跳转
|
||||
if ($method == 'web') {
|
||||
//如果是移动端,但不是微信环境
|
||||
if ($isMobile && !$isWechat) {
|
||||
$method = 'wap';
|
||||
} else {
|
||||
Session::set("wechatorderdata", $params);
|
||||
$url = addon_url('epay/api/wechat', [], true, true);
|
||||
return new RedirectResponse($url);
|
||||
}
|
||||
}
|
||||
|
||||
//单位分
|
||||
$total_fee = function_exists('bcmul') ? bcmul($amount, 100) : $amount * 100;
|
||||
$total_fee = (int)$total_fee;
|
||||
$ip = $request->ip();
|
||||
//微信服务商模式时需传递sub_openid参数
|
||||
$openidName = $addonConfig['wechat']['mode'] == 'service' ? 'sub_openid' : 'openid';
|
||||
|
||||
//创建支付对象
|
||||
$pay = Pay::wechat($config);
|
||||
|
||||
if (self::isVersionV3()) {
|
||||
//V3支付
|
||||
$params = [
|
||||
'out_trade_no' => $orderid,
|
||||
'description' => $title,
|
||||
'amount' => [
|
||||
'total' => $total_fee,
|
||||
]
|
||||
];
|
||||
switch ($method) {
|
||||
case 'mp':
|
||||
//公众号支付
|
||||
//公众号支付必须有openid
|
||||
$params['payer'] = [$openidName => $openid];
|
||||
$result = $pay->mp($params);
|
||||
break;
|
||||
case 'wap':
|
||||
//手机网页支付,跳转
|
||||
$params['scene_info'] = [
|
||||
'payer_client_ip' => $ip,
|
||||
'h5_info' => [
|
||||
'type' => 'Wap',
|
||||
]
|
||||
];
|
||||
$result = $pay->wap($params);
|
||||
break;
|
||||
case 'app':
|
||||
//APP支付,直接返回字符串
|
||||
$result = $pay->app($params);
|
||||
break;
|
||||
case 'scan':
|
||||
//扫码支付,直接返回字符串
|
||||
$result = $pay->scan($params);
|
||||
break;
|
||||
case 'pos':
|
||||
//刷卡支付,直接返回字符串
|
||||
//刷卡支付必须要有auth_code
|
||||
$params['auth_code'] = $auth_code;
|
||||
$result = $pay->pos($params);
|
||||
break;
|
||||
case 'mini':
|
||||
case 'miniapp':
|
||||
//小程序支付,直接返回字符串
|
||||
//小程序支付必须要有openid
|
||||
$params['payer'] = [$openidName => $openid];
|
||||
$result = $pay->mini($params);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
} else {
|
||||
//V2支付
|
||||
$params = [
|
||||
'out_trade_no' => $orderid,
|
||||
'body' => $title,
|
||||
'total_fee' => $total_fee,
|
||||
];
|
||||
switch ($method) {
|
||||
case 'mp':
|
||||
//公众号支付
|
||||
//公众号支付必须有openid
|
||||
$params[$openidName] = $openid;
|
||||
$result = $pay->mp($params);
|
||||
break;
|
||||
case 'wap':
|
||||
//手机网页支付,跳转
|
||||
$params['spbill_create_ip'] = $ip;
|
||||
$result = $pay->wap($params);
|
||||
break;
|
||||
case 'app':
|
||||
//APP支付,直接返回字符串
|
||||
$result = $pay->app($params);
|
||||
break;
|
||||
case 'scan':
|
||||
//扫码支付,直接返回字符串
|
||||
$result = $pay->scan($params);
|
||||
break;
|
||||
case 'pos':
|
||||
//刷卡支付,直接返回字符串
|
||||
//刷卡支付必须要有auth_code
|
||||
$params['auth_code'] = $auth_code;
|
||||
$result = $pay->pos($params);
|
||||
break;
|
||||
case 'mini':
|
||||
case 'miniapp':
|
||||
//小程序支付,直接返回字符串
|
||||
//小程序支付必须要有openid
|
||||
$params[$openidName] = $openid;
|
||||
$result = $pay->miniapp($params);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//使用重写的Response类、RedirectResponse、Collection类
|
||||
if ($result instanceof \Symfony\Component\HttpFoundation\RedirectResponse) {
|
||||
$result = new RedirectResponse($result->getTargetUrl());
|
||||
} elseif ($result instanceof \Symfony\Component\HttpFoundation\Response) {
|
||||
$result = new Response($result->getContent());
|
||||
} elseif ($result instanceof \Yansongda\Supports\Collection) {
|
||||
$result = Collection::make($result->all());
|
||||
} elseif ($result instanceof \GuzzleHttp\Psr7\Response) {
|
||||
$result = new Response($result->getBody());
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证回调是否成功
|
||||
* @param string $type 支付类型
|
||||
* @param array $custom 自定义配置信息
|
||||
* @return bool|\Yansongda\Pay\Gateways\Alipay|\Yansongda\Pay\Gateways\Wechat|\Yansongda\Pay\Provider\Wechat|\Yansongda\Pay\Provider\Alipay
|
||||
*/
|
||||
public static function checkNotify($type, $custom = [])
|
||||
{
|
||||
$type = strtolower($type);
|
||||
if (!in_array($type, ['wechat', 'alipay'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$version = self::getSdkVersion();
|
||||
|
||||
try {
|
||||
$config = self::getConfig($type, $custom);
|
||||
$pay = $type == 'wechat' ? Pay::wechat($config) : Pay::alipay($config);
|
||||
|
||||
$data = Service::isVersionV3() ? $pay->callback() : $pay->verify();
|
||||
if ($type == 'alipay') {
|
||||
if (in_array($data['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
|
||||
return $pay;
|
||||
}
|
||||
} else {
|
||||
return $pay;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
\think\Log::record("回调请求参数解析错误", "error");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证返回是否成功,请勿用于判断是否支付成功的逻辑验证
|
||||
* 已弃用
|
||||
*
|
||||
* @param string $type 支付类型
|
||||
* @param array $custom 自定义配置信息
|
||||
* @return bool
|
||||
* @deprecated 已弃用,请勿用于逻辑验证
|
||||
*/
|
||||
public static function checkReturn($type, $custom = [])
|
||||
{
|
||||
//由于PC及移动端无法获取请求的参数信息,取消return验证,均返回true
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理证书路径
|
||||
* @param array $config 配置
|
||||
* @param string $field 字段
|
||||
* @return void
|
||||
*/
|
||||
private static function processAddonsPath(&$config, $field)
|
||||
{
|
||||
if (isset($config[$field]) && substr($config[$field], 0, 8) == '/addons/') {
|
||||
$config[$field] = ROOT_PATH . str_replace('/', DS, substr($config[$field], 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
* @param string $type 支付类型
|
||||
* @param array $custom 自定义配置,用于覆盖插件默认配置
|
||||
* @return array
|
||||
*/
|
||||
public static function getConfig($type = 'wechat', $custom = [])
|
||||
{
|
||||
$addonConfig = get_addon_config('epay');
|
||||
$config = $addonConfig[$type] ?? $addonConfig['wechat'];
|
||||
|
||||
// SDK版本
|
||||
$version = self::getSdkVersion();
|
||||
|
||||
// 处理微信证书路径
|
||||
if ($type === 'wechat') {
|
||||
$certFields = ['cert_client', 'cert_key'];
|
||||
foreach ($certFields as $field) {
|
||||
self::processAddonsPath($config, $field);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理支付宝证书路径
|
||||
if ($type === 'alipay') {
|
||||
$config['signtype'] = $config['signtype'] ?? 'publickey';
|
||||
if ($config['signtype'] == 'cert') {
|
||||
$certFields = ['app_cert_public_key', 'alipay_root_cert', 'ali_public_key'];
|
||||
foreach ($certFields as $field) {
|
||||
self::processAddonsPath($config, $field);
|
||||
}
|
||||
} else {
|
||||
// 如果是普通公钥需要将app_cert_public_key和alipay_root_cert设置为空,不然会导致错误
|
||||
$config['app_cert_public_key'] = '';
|
||||
$config['alipay_root_cert'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
// V3支付
|
||||
if (self::isVersionV3()) {
|
||||
if ($type == 'wechat') {
|
||||
$config['mp_app_id'] = $config['app_id'] ?? '';
|
||||
$config['app_id'] = $config['appid'] ?? '';
|
||||
$config['mini_app_id'] = $config['miniapp_id'] ?? '';
|
||||
$config['combine_mch_id'] = $config['combine_mch_id'] ?? '';
|
||||
$config['mch_secret_key'] = $config['key_v3'] ?? '';
|
||||
$config['mch_secret_cert'] = $config['cert_key'];
|
||||
$config['mch_public_cert_path'] = $config['cert_client'];
|
||||
|
||||
$config['sub_mp_app_id'] = $config['sub_appid'] ?? '';
|
||||
$config['sub_app_id'] = $config['sub_app_id'] ?? '';
|
||||
$config['sub_mini_app_id'] = $config['sub_miniapp_id'] ?? '';
|
||||
$config['sub_mch_id'] = $config['sub_mch_id'] ?? '';
|
||||
} elseif ($type == 'alipay') {
|
||||
$config['app_secret_cert'] = $config['private_key'] ?? '';
|
||||
$config['app_public_cert_path'] = $config['app_cert_public_key'] ?? '';
|
||||
$config['alipay_public_cert_path'] = $config['ali_public_key'] ?? '';
|
||||
$config['alipay_root_cert_path'] = $config['alipay_root_cert'] ?? '';
|
||||
$config['service_provider_id'] = $config['pid'] ?? '';
|
||||
}
|
||||
$modeArr = ['normal' => 0, 'dev' => 1, 'service' => 2];
|
||||
$config['mode'] = $modeArr[$config['mode']] ?? 0;
|
||||
}
|
||||
|
||||
// 日志
|
||||
if ($config['log']) {
|
||||
$config['log'] = [
|
||||
'enable' => true,
|
||||
'file' => LOG_PATH . 'epaylogs' . DS . $type . '-' . date("Y-m-d") . '.log',
|
||||
'level' => 'debug'
|
||||
];
|
||||
} else {
|
||||
$config['log'] = [
|
||||
'enable' => false,
|
||||
];
|
||||
}
|
||||
|
||||
// GuzzleHttp配置,可选
|
||||
$config['http'] = [
|
||||
'timeout' => 10,
|
||||
'connect_timeout' => 10,
|
||||
// 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
|
||||
];
|
||||
|
||||
$config['notify_url'] = empty($config['notify_url']) ? addon_url('epay/api/notifyx', [], false) . '/type/' . $type : $config['notify_url'];
|
||||
$config['notify_url'] = !preg_match("/^(http:\/\/|https:\/\/)/i", $config['notify_url']) ? request()->root(true) . $config['notify_url'] : $config['notify_url'];
|
||||
$config['return_url'] = empty($config['return_url']) ? addon_url('epay/api/returnx', [], false) . '/type/' . $type : $config['return_url'];
|
||||
$config['return_url'] = !preg_match("/^(http:\/\/|https:\/\/)/i", $config['return_url']) ? request()->root(true) . $config['return_url'] : $config['return_url'];
|
||||
|
||||
//合并自定义配置
|
||||
$config = array_merge($config, $custom);
|
||||
|
||||
//v3版本时返回的结构不同
|
||||
if (self::isVersionV3()) {
|
||||
$config = [$type => ['default' => $config], 'logger' => $config['log'], 'http' => $config['http'], '_force' => true];
|
||||
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信Openid
|
||||
*
|
||||
* @param array $custom 自定义配置信息
|
||||
* @return mixed|string
|
||||
*/
|
||||
public static function getOpenid($custom = [])
|
||||
{
|
||||
$openid = '';
|
||||
$auth = Auth::instance();
|
||||
if ($auth->isLogin()) {
|
||||
$third = get_addon_info('third');
|
||||
if ($third && $third['state']) {
|
||||
$thirdInfo = Third::where('user_id', $auth->id)->where('platform', 'wechat')->where('apptype', 'mp')->find();
|
||||
$openid = $thirdInfo ? $thirdInfo['openid'] : '';
|
||||
}
|
||||
}
|
||||
if (!$openid) {
|
||||
$openid = Session::get("openid");
|
||||
|
||||
//如果未传openid,则去读取openid
|
||||
if (!$openid) {
|
||||
$addonConfig = get_addon_config('epay');
|
||||
$wechat = new Wechat($custom['app_id'] ?? $addonConfig['wechat']['app_id'], $custom['app_secret'] ?? $addonConfig['wechat']['app_secret']);
|
||||
$openid = $wechat->getOpenid();
|
||||
}
|
||||
}
|
||||
return $openid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取SDK版本
|
||||
* @return mixed|string
|
||||
*/
|
||||
public static function getSdkVersion()
|
||||
{
|
||||
$addonConfig = get_addon_config('epay');
|
||||
return $addonConfig['version'] ?? self::SDK_VERSION_V2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否V2支付
|
||||
* @return bool
|
||||
*/
|
||||
public static function isVersionV2()
|
||||
{
|
||||
return self::getSdkVersion() === self::SDK_VERSION_V2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否V3支付
|
||||
* @return bool
|
||||
*/
|
||||
public static function isVersionV3()
|
||||
{
|
||||
return self::getSdkVersion() === self::SDK_VERSION_V3;
|
||||
}
|
||||
}
|
||||
110
addons/epay/library/Wechat.php
Normal file
110
addons/epay/library/Wechat.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace addons\epay\library;
|
||||
|
||||
use fast\Http;
|
||||
use think\Cache;
|
||||
use think\Session;
|
||||
|
||||
/**
|
||||
* 微信授权
|
||||
*
|
||||
*/
|
||||
class Wechat
|
||||
{
|
||||
private $app_id = '';
|
||||
private $app_secret = '';
|
||||
private $scope = 'snsapi_userinfo';
|
||||
|
||||
public function __construct($app_id, $app_secret)
|
||||
{
|
||||
$this->app_id = $app_id;
|
||||
$this->app_secret = $app_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信授权链接
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthorizeUrl()
|
||||
{
|
||||
$redirect_uri = addon_url('epay/api/wechat', [], true, true);
|
||||
$redirect_uri = urlencode($redirect_uri);
|
||||
$state = \fast\Random::alnum();
|
||||
Session::set('state', $state);
|
||||
return "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->app_id}&redirect_uri={$redirect_uri}&response_type=code&scope={$this->scope}&state={$state}#wechat_redirect";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信openid
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function getOpenid()
|
||||
{
|
||||
$openid = Session::get('openid');
|
||||
if (!$openid) {
|
||||
if (!isset($_GET['code'])) {
|
||||
$url = $this->getAuthorizeUrl();
|
||||
|
||||
Header("Location: $url");
|
||||
exit();
|
||||
} else {
|
||||
$state = Session::get('state');
|
||||
if ($state == $_GET['state']) {
|
||||
$code = $_GET['code'];
|
||||
$token = $this->getAccessToken($code);
|
||||
if (!isset($token['openid']) && isset($token['errmsg'])) {
|
||||
exception($token['errmsg']);
|
||||
}
|
||||
$openid = $token['openid'] ?? '';
|
||||
if ($openid) {
|
||||
Session::set("openid", $openid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $openid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取授权token网页授权
|
||||
*
|
||||
* @param string $code
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function getAccessToken($code = '')
|
||||
{
|
||||
$params = [
|
||||
'appid' => $this->app_id,
|
||||
'secret' => $this->app_secret,
|
||||
'code' => $code,
|
||||
'grant_type' => 'authorization_code'
|
||||
];
|
||||
$ret = Http::sendRequest('https://api.weixin.qq.com/sns/oauth2/access_token', $params, 'GET');
|
||||
if ($ret['ret']) {
|
||||
$ar = json_decode($ret['msg'], true);
|
||||
return $ar;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getJsticket($code = '')
|
||||
{
|
||||
$jsticket = Session::get('jsticket');
|
||||
if (!$jsticket) {
|
||||
$token = $this->getAccessToken($code);
|
||||
$params = [
|
||||
'access_token' => 'token',
|
||||
'type' => 'jsapi',
|
||||
];
|
||||
$ret = Http::sendRequest('https://api.weixin.qq.com/cgi-bin/ticket/getticket', $params, 'GET');
|
||||
if ($ret['ret']) {
|
||||
$ar = json_decode($ret['msg'], true);
|
||||
return $ar;
|
||||
}
|
||||
}
|
||||
return $jsticket;
|
||||
}
|
||||
}
|
||||
2
addons/epay/library/hyperf/context/.gitattributes
vendored
Normal file
2
addons/epay/library/hyperf/context/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/tests export-ignore
|
||||
/.github export-ignore
|
||||
21
addons/epay/library/hyperf/context/LICENSE
Normal file
21
addons/epay/library/hyperf/context/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Hyperf
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
40
addons/epay/library/hyperf/context/composer.json
Normal file
40
addons/epay/library/hyperf/context/composer.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "hyperf/context",
|
||||
"description": "A coroutine context library.",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"php",
|
||||
"swoole",
|
||||
"hyperf",
|
||||
"context"
|
||||
],
|
||||
"homepage": "https://hyperf.io",
|
||||
"support": {
|
||||
"docs": "https://hyperf.wiki",
|
||||
"issues": "https://github.com/hyperf/hyperf/issues",
|
||||
"pull-request": "https://github.com/hyperf/hyperf/pulls",
|
||||
"source": "https://github.com/hyperf/hyperf"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"hyperf/engine": "^1.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hyperf\\Context\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"HyperfTest\\Context\\": "tests/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
112
addons/epay/library/hyperf/context/src/Context.php
Normal file
112
addons/epay/library/hyperf/context/src/Context.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Context;
|
||||
|
||||
use Hyperf\Engine\Coroutine;
|
||||
|
||||
class Context
|
||||
{
|
||||
protected static $nonCoContext = [];
|
||||
|
||||
public static function set(string $id, $value)
|
||||
{
|
||||
if (Coroutine::id() > 0) {
|
||||
Coroutine::getContextFor()[$id] = $value;
|
||||
} else {
|
||||
static::$nonCoContext[$id] = $value;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function get(string $id, $default = null, $coroutineId = null)
|
||||
{
|
||||
if (Coroutine::id() > 0) {
|
||||
return Coroutine::getContextFor($coroutineId)[$id] ?? $default;
|
||||
}
|
||||
|
||||
return static::$nonCoContext[$id] ?? $default;
|
||||
}
|
||||
|
||||
public static function has(string $id, $coroutineId = null)
|
||||
{
|
||||
if (Coroutine::id() > 0) {
|
||||
return isset(Coroutine::getContextFor($coroutineId)[$id]);
|
||||
}
|
||||
|
||||
return isset(static::$nonCoContext[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the context when you are not in coroutine environment.
|
||||
*/
|
||||
public static function destroy(string $id)
|
||||
{
|
||||
unset(static::$nonCoContext[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the context from a coroutine to current coroutine.
|
||||
* This method will delete the origin values in current coroutine.
|
||||
*/
|
||||
public static function copy(int $fromCoroutineId, array $keys = []): void
|
||||
{
|
||||
$from = Coroutine::getContextFor($fromCoroutineId);
|
||||
if ($from === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current = Coroutine::getContextFor();
|
||||
|
||||
if ($keys) {
|
||||
$map = array_intersect_key($from->getArrayCopy(), array_flip($keys));
|
||||
} else {
|
||||
$map = $from->getArrayCopy();
|
||||
}
|
||||
|
||||
$current->exchangeArray($map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value and override it by closure.
|
||||
*/
|
||||
public static function override(string $id, \Closure $closure)
|
||||
{
|
||||
$value = null;
|
||||
if (self::has($id)) {
|
||||
$value = self::get($id);
|
||||
}
|
||||
$value = $closure($value);
|
||||
self::set($id, $value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value and store it if not exists.
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function getOrSet(string $id, $value)
|
||||
{
|
||||
if (! self::has($id)) {
|
||||
return self::set($id, value($value));
|
||||
}
|
||||
return self::get($id);
|
||||
}
|
||||
|
||||
public static function getContainer()
|
||||
{
|
||||
if (Coroutine::id() > 0) {
|
||||
return Coroutine::getContextFor();
|
||||
}
|
||||
|
||||
return static::$nonCoContext;
|
||||
}
|
||||
}
|
||||
2
addons/epay/library/hyperf/contract/.gitattributes
vendored
Normal file
2
addons/epay/library/hyperf/contract/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/tests export-ignore
|
||||
/.github export-ignore
|
||||
21
addons/epay/library/hyperf/contract/LICENSE
Normal file
21
addons/epay/library/hyperf/contract/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Hyperf
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
33
addons/epay/library/hyperf/contract/composer.json
Normal file
33
addons/epay/library/hyperf/contract/composer.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "hyperf/contract",
|
||||
"description": "The contracts of Hyperf.",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"php",
|
||||
"swoole",
|
||||
"hyperf"
|
||||
],
|
||||
"homepage": "https://hyperf.io",
|
||||
"support": {
|
||||
"docs": "https://hyperf.wiki",
|
||||
"issues": "https://github.com/hyperf/hyperf/issues",
|
||||
"pull-request": "https://github.com/hyperf/hyperf/pulls",
|
||||
"source": "https://github.com/hyperf/hyperf"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hyperf\\Contract\\": "src/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface ApplicationInterface
|
||||
{
|
||||
}
|
||||
22
addons/epay/library/hyperf/contract/src/Castable.php
Normal file
22
addons/epay/library/hyperf/contract/src/Castable.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface Castable
|
||||
{
|
||||
/**
|
||||
* Get the name of the caster class to use when casting from / to this cast target.
|
||||
*
|
||||
* @return CastsAttributes|CastsInboundAttributes|string
|
||||
*/
|
||||
public static function castUsing();
|
||||
}
|
||||
33
addons/epay/library/hyperf/contract/src/CastsAttributes.php
Normal file
33
addons/epay/library/hyperf/contract/src/CastsAttributes.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Transform the attribute from the underlying model values.
|
||||
*
|
||||
* @param object $model
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes);
|
||||
|
||||
/**
|
||||
* Transform the attribute to its underlying model values.
|
||||
*
|
||||
* @param object $model
|
||||
* @param mixed $value
|
||||
* @return array|string
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface CastsInboundAttributes
|
||||
{
|
||||
/**
|
||||
* Transform the attribute to its underlying model values.
|
||||
*
|
||||
* @param object $model
|
||||
* @param mixed $value
|
||||
* @return array
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface CompressInterface
|
||||
{
|
||||
public function compress(): UnCompressInterface;
|
||||
}
|
||||
41
addons/epay/library/hyperf/contract/src/ConfigInterface.php
Normal file
41
addons/epay/library/hyperf/contract/src/ConfigInterface.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface ConfigInterface
|
||||
{
|
||||
/**
|
||||
* Finds an entry of the container by its identifier and returns it.
|
||||
*
|
||||
* @param string $key identifier of the entry to look for
|
||||
* @param mixed $default default value of the entry when does not found
|
||||
* @return mixed entry
|
||||
*/
|
||||
public function get(string $key, $default = null);
|
||||
|
||||
/**
|
||||
* Returns true if the container can return an entry for the given identifier.
|
||||
* Returns false otherwise.
|
||||
*
|
||||
* @param string $keys identifier of the entry to look for
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $keys);
|
||||
|
||||
/**
|
||||
* Set a value to the container by its identifier.
|
||||
*
|
||||
* @param string $key identifier of the entry to set
|
||||
* @param mixed $value the value that save to container
|
||||
*/
|
||||
public function set(string $key, $value);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface ConnectionInterface
|
||||
{
|
||||
/**
|
||||
* Get the real connection from pool.
|
||||
*/
|
||||
public function getConnection();
|
||||
|
||||
/**
|
||||
* Reconnect the connection.
|
||||
*/
|
||||
public function reconnect(): bool;
|
||||
|
||||
/**
|
||||
* Check the connection is valid.
|
||||
*/
|
||||
public function check(): bool;
|
||||
|
||||
/**
|
||||
* Close the connection.
|
||||
*/
|
||||
public function close(): bool;
|
||||
|
||||
/**
|
||||
* Release the connection to pool.
|
||||
*/
|
||||
public function release(): void;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Psr\Container\ContainerInterface as PsrContainerInterface;
|
||||
|
||||
interface ContainerInterface extends PsrContainerInterface
|
||||
{
|
||||
/**
|
||||
* Build an entry of the container by its name.
|
||||
* This method behave like get() except resolves the entry again every time.
|
||||
* For example if the entry is a class then a new instance will be created each time.
|
||||
* This method makes the container behave like a factory.
|
||||
*
|
||||
* @param string $name entry name or a class name
|
||||
* @param array $parameters Optional parameters to use to build the entry. Use this to force specific parameters
|
||||
* to specific values. Parameters not defined in this array will be resolved using
|
||||
* the container.
|
||||
* @throws InvalidArgumentException the name parameter must be of type string
|
||||
* @throws NotFoundException no entry found for the given name
|
||||
*/
|
||||
public function make(string $name, array $parameters = []);
|
||||
|
||||
/**
|
||||
* Bind an arbitrary resolved entry to an identifier.
|
||||
* Useful for testing 'get'.
|
||||
*
|
||||
* @param mixed $entry
|
||||
*/
|
||||
public function set(string $name, $entry);
|
||||
|
||||
/**
|
||||
* Unbind an arbitrary resolved entry.
|
||||
*/
|
||||
public function unbind(string $name);
|
||||
|
||||
/**
|
||||
* Bind an arbitrary definition to an identifier.
|
||||
* Useful for testing 'make'.
|
||||
*
|
||||
* @param array|callable|string $definition
|
||||
*/
|
||||
public function define(string $name, $definition);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface DispatcherInterface
|
||||
{
|
||||
public function dispatch(...$params);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface FrequencyInterface
|
||||
{
|
||||
/**
|
||||
* Number of hit per time.
|
||||
*/
|
||||
public function hit(int $number = 1): bool;
|
||||
|
||||
/**
|
||||
* Hits per second.
|
||||
*/
|
||||
public function frequency(): float;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface IdGeneratorInterface
|
||||
{
|
||||
public function generate();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface LengthAwarePaginatorInterface extends PaginatorInterface
|
||||
{
|
||||
/**
|
||||
* Create a range of pagination URLs.
|
||||
*/
|
||||
public function getUrlRange(int $start, int $end): array;
|
||||
|
||||
/**
|
||||
* Determine the total number of items in the data store.
|
||||
*/
|
||||
public function total(): int;
|
||||
|
||||
/**
|
||||
* Get the page number of the last available page.
|
||||
*/
|
||||
public function lastPage(): int;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface MiddlewareInitializerInterface
|
||||
{
|
||||
public function initCoreMiddleware(string $serverName): void;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface NormalizerInterface
|
||||
{
|
||||
/**
|
||||
* Normalizes an object into a set of arrays/scalars.
|
||||
*
|
||||
* @param mixed $object
|
||||
* @return null|array|\ArrayObject|bool|float|int|string
|
||||
*/
|
||||
public function normalize($object);
|
||||
|
||||
/**
|
||||
* Denormalizes data back into an object of the given class.
|
||||
*
|
||||
* @param mixed $data Data to restore
|
||||
* @param string $class The expected class to instantiate
|
||||
* @return mixed|object
|
||||
*/
|
||||
public function denormalize($data, string $class);
|
||||
}
|
||||
23
addons/epay/library/hyperf/contract/src/OnCloseInterface.php
Normal file
23
addons/epay/library/hyperf/contract/src/OnCloseInterface.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\Server;
|
||||
|
||||
interface OnCloseInterface
|
||||
{
|
||||
/**
|
||||
* @param Response|Server $server
|
||||
*/
|
||||
public function onClose($server, int $fd, int $reactorId): void;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
|
||||
interface OnHandShakeInterface
|
||||
{
|
||||
public function onHandShake(Request $request, Response $response): void;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\WebSocket\Frame;
|
||||
use Swoole\WebSocket\Server;
|
||||
|
||||
interface OnMessageInterface
|
||||
{
|
||||
/**
|
||||
* @param Response|Server $server
|
||||
*/
|
||||
public function onMessage($server, Frame $frame): void;
|
||||
}
|
||||
24
addons/epay/library/hyperf/contract/src/OnOpenInterface.php
Normal file
24
addons/epay/library/hyperf/contract/src/OnOpenInterface.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\WebSocket\Server;
|
||||
|
||||
interface OnOpenInterface
|
||||
{
|
||||
/**
|
||||
* @param Response|Server $server
|
||||
*/
|
||||
public function onOpen($server, Request $request): void;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Swoole\WebSocket\Server;
|
||||
|
||||
interface OnPacketInterface
|
||||
{
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param mixed $data
|
||||
* @param array $clientInfo
|
||||
*/
|
||||
public function onPacket($server, $data, $clientInfo): void;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Swoole\Coroutine\Server\Connection;
|
||||
use Swoole\Server as SwooleServer;
|
||||
|
||||
interface OnReceiveInterface
|
||||
{
|
||||
/**
|
||||
* @param Connection|SwooleServer $server
|
||||
*/
|
||||
public function onReceive($server, int $fd, int $reactorId, string $data): void;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface OnRequestInterface
|
||||
{
|
||||
/**
|
||||
* @param mixed $request swoole request or psr server request
|
||||
* @param mixed $response swoole response or swow session
|
||||
*/
|
||||
public function onRequest($request, $response): void;
|
||||
}
|
||||
19
addons/epay/library/hyperf/contract/src/PackerInterface.php
Normal file
19
addons/epay/library/hyperf/contract/src/PackerInterface.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface PackerInterface
|
||||
{
|
||||
public function pack($data): string;
|
||||
|
||||
public function unpack(string $data);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface PaginatorInterface
|
||||
{
|
||||
/**
|
||||
* Get the URL for a given page.
|
||||
*/
|
||||
public function url(int $page): string;
|
||||
|
||||
/**
|
||||
* Add a set of query string values to the paginator.
|
||||
*
|
||||
* @param array|string $key
|
||||
* @return $this
|
||||
*/
|
||||
public function appends($key, ?string $value = null);
|
||||
|
||||
/**
|
||||
* Get / set the URL fragment to be appended to URLs.
|
||||
*
|
||||
* @return $this|string
|
||||
*/
|
||||
public function fragment(?string $fragment = null);
|
||||
|
||||
/**
|
||||
* The URL for the next page, or null.
|
||||
*/
|
||||
public function nextPageUrl(): ?string;
|
||||
|
||||
/**
|
||||
* Get the URL for the previous page, or null.
|
||||
*/
|
||||
public function previousPageUrl(): ?string;
|
||||
|
||||
/**
|
||||
* Get all of the items being paginated.
|
||||
*/
|
||||
public function items(): array;
|
||||
|
||||
/**
|
||||
* Get the "index" of the first item being paginated.
|
||||
*/
|
||||
public function firstItem(): ?int;
|
||||
|
||||
/**
|
||||
* Get the "index" of the last item being paginated.
|
||||
*/
|
||||
public function lastItem(): ?int;
|
||||
|
||||
/**
|
||||
* Determine how many items are being shown per page.
|
||||
*/
|
||||
public function perPage(): int;
|
||||
|
||||
/**
|
||||
* Determine the current page being paginated.
|
||||
*/
|
||||
public function currentPage(): int;
|
||||
|
||||
/**
|
||||
* Determine if there are enough items to split into multiple pages.
|
||||
*/
|
||||
public function hasPages(): bool;
|
||||
|
||||
/**
|
||||
* Determine if there is more items in the data store.
|
||||
*/
|
||||
public function hasMorePages(): bool;
|
||||
|
||||
/**
|
||||
* Determine if the list of items is empty or not.
|
||||
*/
|
||||
public function isEmpty(): bool;
|
||||
|
||||
/**
|
||||
* Determine if the list of items is not empty.
|
||||
*/
|
||||
public function isNotEmpty(): bool;
|
||||
|
||||
/**
|
||||
* Render the paginator using a given view.
|
||||
*/
|
||||
public function render(?string $view = null, array $data = []): string;
|
||||
}
|
||||
30
addons/epay/library/hyperf/contract/src/PoolInterface.php
Normal file
30
addons/epay/library/hyperf/contract/src/PoolInterface.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface PoolInterface
|
||||
{
|
||||
/**
|
||||
* Get a connection from the connection pool.
|
||||
*/
|
||||
public function get(): ConnectionInterface;
|
||||
|
||||
/**
|
||||
* Release a connection back to the connection pool.
|
||||
*/
|
||||
public function release(ConnectionInterface $connection): void;
|
||||
|
||||
/**
|
||||
* Close and clear the connection pool.
|
||||
*/
|
||||
public function flush(): void;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface PoolOptionInterface
|
||||
{
|
||||
public function getMaxConnections(): int;
|
||||
|
||||
public function getMinConnections(): int;
|
||||
|
||||
public function getConnectTimeout(): float;
|
||||
|
||||
public function getWaitTimeout(): float;
|
||||
|
||||
public function getHeartbeat(): float;
|
||||
|
||||
public function getMaxIdleTime(): float;
|
||||
}
|
||||
36
addons/epay/library/hyperf/contract/src/ProcessInterface.php
Normal file
36
addons/epay/library/hyperf/contract/src/ProcessInterface.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Swoole\Coroutine\Http\Server as CoHttpServer;
|
||||
use Swoole\Coroutine\Server as CoServer;
|
||||
use Swoole\Server;
|
||||
|
||||
interface ProcessInterface
|
||||
{
|
||||
/**
|
||||
* Create the process object according to process number and bind to server.
|
||||
* @param CoHttpServer|CoServer|Server $server
|
||||
*/
|
||||
public function bind($server): void;
|
||||
|
||||
/**
|
||||
* Determine if the process should start ?
|
||||
* @param CoServer|Server $server
|
||||
*/
|
||||
public function isEnable($server): bool;
|
||||
|
||||
/**
|
||||
* The logical of process will place in here.
|
||||
*/
|
||||
public function handle(): void;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
interface ResponseEmitterInterface
|
||||
{
|
||||
/**
|
||||
* @param mixed $connection swoole response or swow session
|
||||
*/
|
||||
public function emit(ResponseInterface $response, $connection, bool $withContent = true);
|
||||
}
|
||||
158
addons/epay/library/hyperf/contract/src/SessionInterface.php
Normal file
158
addons/epay/library/hyperf/contract/src/SessionInterface.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface SessionInterface
|
||||
{
|
||||
/**
|
||||
* Starts the session storage.
|
||||
*
|
||||
* @throws \RuntimeException if session fails to start
|
||||
* @return bool True if session started
|
||||
*/
|
||||
public function start(): bool;
|
||||
|
||||
/**
|
||||
* Returns the session ID.
|
||||
*
|
||||
* @return string The session ID
|
||||
*/
|
||||
public function getId(): string;
|
||||
|
||||
/**
|
||||
* Sets the session ID.
|
||||
*/
|
||||
public function setId(string $id);
|
||||
|
||||
/**
|
||||
* Returns the session name.
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Sets the session name.
|
||||
*/
|
||||
public function setName(string $name);
|
||||
|
||||
/**
|
||||
* Invalidates the current session.
|
||||
*
|
||||
* Clears all session attributes and flashes and regenerates the
|
||||
* session and deletes the old session from persistence.
|
||||
*
|
||||
* @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
|
||||
* will leave the system settings unchanged, 0 sets the cookie
|
||||
* to expire with browser session. Time is in seconds, and is
|
||||
* not a Unix timestamp.
|
||||
*
|
||||
* @return bool True if session invalidated, false if error
|
||||
*/
|
||||
public function invalidate(?int $lifetime = null): bool;
|
||||
|
||||
/**
|
||||
* Migrates the current session to a new session id while maintaining all
|
||||
* session attributes.
|
||||
*
|
||||
* @param bool $destroy Whether to delete the old session or leave it to garbage collection
|
||||
* @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
|
||||
* will leave the system settings unchanged, 0 sets the cookie
|
||||
* to expire with browser session. Time is in seconds, and is
|
||||
* not a Unix timestamp.
|
||||
*
|
||||
* @return bool True if session migrated, false if error
|
||||
*/
|
||||
public function migrate(bool $destroy = false, ?int $lifetime = null): bool;
|
||||
|
||||
/**
|
||||
* Force the session to be saved and closed.
|
||||
*
|
||||
* This method is generally not required for real sessions as
|
||||
* the session will be automatically saved at the end of
|
||||
* code execution.
|
||||
*/
|
||||
public function save(): void;
|
||||
|
||||
/**
|
||||
* Checks if an attribute is defined.
|
||||
*
|
||||
* @param string $name The attribute name
|
||||
*
|
||||
* @return bool true if the attribute is defined, false otherwise
|
||||
*/
|
||||
public function has(string $name): bool;
|
||||
|
||||
/**
|
||||
* Returns an attribute.
|
||||
*
|
||||
* @param string $name The attribute name
|
||||
* @param mixed $default The default value if not found
|
||||
*/
|
||||
public function get(string $name, $default = null);
|
||||
|
||||
/**
|
||||
* Sets an attribute.
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set(string $name, $value): void;
|
||||
|
||||
/**
|
||||
* Put a key / value pair or array of key / value pairs in the session.
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param null|mixed $value
|
||||
*/
|
||||
public function put($key, $value = null): void;
|
||||
|
||||
/**
|
||||
* Returns attributes.
|
||||
*/
|
||||
public function all(): array;
|
||||
|
||||
/**
|
||||
* Sets attributes.
|
||||
*/
|
||||
public function replace(array $attributes): void;
|
||||
|
||||
/**
|
||||
* Removes an attribute, returning its value.
|
||||
*
|
||||
* @return mixed The removed value or null when it does not exist
|
||||
*/
|
||||
public function remove(string $name);
|
||||
|
||||
/**
|
||||
* Remove one or many items from the session.
|
||||
*
|
||||
* @param array|string $keys
|
||||
*/
|
||||
public function forget($keys): void;
|
||||
|
||||
/**
|
||||
* Clears all attributes.
|
||||
*/
|
||||
public function clear(): void;
|
||||
|
||||
/**
|
||||
* Checks if the session was started.
|
||||
*/
|
||||
public function isStarted(): bool;
|
||||
|
||||
/**
|
||||
* Get the previous URL from the session.
|
||||
*/
|
||||
public function previousUrl(): ?string;
|
||||
|
||||
/**
|
||||
* Set the "previous" URL in the session.
|
||||
*/
|
||||
public function setPreviousUrl(string $url): void;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
interface StdoutLoggerInterface extends LoggerInterface
|
||||
{
|
||||
}
|
||||
20
addons/epay/library/hyperf/contract/src/Synchronized.php
Normal file
20
addons/epay/library/hyperf/contract/src/Synchronized.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface Synchronized
|
||||
{
|
||||
/**
|
||||
* Whether the data has been synchronized.
|
||||
*/
|
||||
public function isSynchronized(): bool;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface TranslatorInterface
|
||||
{
|
||||
/**
|
||||
* Get the translation for a given key.
|
||||
*/
|
||||
public function trans(string $key, array $replace = [], ?string $locale = null);
|
||||
|
||||
/**
|
||||
* Get a translation according to an integer value.
|
||||
*
|
||||
* @param array|\Countable|int $number
|
||||
*/
|
||||
public function transChoice(string $key, $number, array $replace = [], ?string $locale = null): string;
|
||||
|
||||
/**
|
||||
* Get the default locale being used.
|
||||
*/
|
||||
public function getLocale(): string;
|
||||
|
||||
/**
|
||||
* Set the default locale.
|
||||
*/
|
||||
public function setLocale(string $locale);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface TranslatorLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Load the messages for the given locale.
|
||||
*/
|
||||
public function load(string $locale, string $group, ?string $namespace = null): array;
|
||||
|
||||
/**
|
||||
* Add a new namespace to the loader.
|
||||
*/
|
||||
public function addNamespace(string $namespace, string $hint);
|
||||
|
||||
/**
|
||||
* Add a new JSON path to the loader.
|
||||
*/
|
||||
public function addJsonPath(string $path);
|
||||
|
||||
/**
|
||||
* Get an array of all the registered namespaces.
|
||||
*/
|
||||
public function namespaces(): array;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
interface UnCompressInterface
|
||||
{
|
||||
public function uncompress();
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Contract;
|
||||
|
||||
use Hyperf\Utils\Contracts\MessageBag;
|
||||
use Hyperf\Utils\Contracts\MessageProvider;
|
||||
|
||||
interface ValidatorInterface extends MessageProvider
|
||||
{
|
||||
/**
|
||||
* Run the validator's rules against its data.
|
||||
*/
|
||||
public function validate(): array;
|
||||
|
||||
/**
|
||||
* Get the attributes and values that were validated.
|
||||
*/
|
||||
public function validated(): array;
|
||||
|
||||
/**
|
||||
* Determine if the data fails the validation rules.
|
||||
*/
|
||||
public function fails(): bool;
|
||||
|
||||
/**
|
||||
* Get the failed validation rules.
|
||||
*/
|
||||
public function failed(): array;
|
||||
|
||||
/**
|
||||
* Add conditions to a given field based on a Closure.
|
||||
*
|
||||
* @param array|string $attribute
|
||||
* @param array|string $rules
|
||||
* @return $this
|
||||
*/
|
||||
public function sometimes($attribute, $rules, callable $callback);
|
||||
|
||||
/**
|
||||
* Add an after validation callback.
|
||||
*
|
||||
* @param callable|string $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function after($callback);
|
||||
|
||||
/**
|
||||
* Get all of the validation error messages.
|
||||
*/
|
||||
public function errors(): MessageBag;
|
||||
}
|
||||
4
addons/epay/library/hyperf/engine/.gitattributes
vendored
Normal file
4
addons/epay/library/hyperf/engine/.gitattributes
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/.github export-ignore
|
||||
/examples export-ignore
|
||||
/tests export-ignore
|
||||
|
||||
4
addons/epay/library/hyperf/engine/.gitignore
vendored
Normal file
4
addons/epay/library/hyperf/engine/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/vendor/
|
||||
composer.lock
|
||||
*.cache
|
||||
*.log
|
||||
89
addons/epay/library/hyperf/engine/.php-cs-fixer.php
Normal file
89
addons/epay/library/hyperf/engine/.php-cs-fixer.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
$header = <<<'EOF'
|
||||
This file is part of Hyperf.
|
||||
|
||||
@link https://www.hyperf.io
|
||||
@document https://hyperf.wiki
|
||||
@contact group@hyperf.io
|
||||
@license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
EOF;
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'@Symfony' => true,
|
||||
'@DoctrineAnnotation' => true,
|
||||
'@PhpCsFixer' => true,
|
||||
'header_comment' => [
|
||||
'comment_type' => 'PHPDoc',
|
||||
'header' => $header,
|
||||
'separate' => 'none',
|
||||
'location' => 'after_declare_strict',
|
||||
],
|
||||
'array_syntax' => [
|
||||
'syntax' => 'short'
|
||||
],
|
||||
'list_syntax' => [
|
||||
'syntax' => 'short'
|
||||
],
|
||||
'concat_space' => [
|
||||
'spacing' => 'one'
|
||||
],
|
||||
'blank_line_before_statement' => [
|
||||
'statements' => [
|
||||
'declare',
|
||||
],
|
||||
],
|
||||
'general_phpdoc_annotation_remove' => [
|
||||
'annotations' => [
|
||||
'author'
|
||||
],
|
||||
],
|
||||
'ordered_imports' => [
|
||||
'imports_order' => [
|
||||
'class', 'function', 'const',
|
||||
],
|
||||
'sort_algorithm' => 'alpha',
|
||||
],
|
||||
'single_line_comment_style' => [
|
||||
'comment_types' => [
|
||||
],
|
||||
],
|
||||
'yoda_style' => [
|
||||
'always_move_variable' => false,
|
||||
'equal' => false,
|
||||
'identical' => false,
|
||||
],
|
||||
'phpdoc_align' => [
|
||||
'align' => 'left',
|
||||
],
|
||||
'multiline_whitespace_before_semicolons' => [
|
||||
'strategy' => 'no_multi_line',
|
||||
],
|
||||
'constant_case' => [
|
||||
'case' => 'lower',
|
||||
],
|
||||
'class_attributes_separation' => true,
|
||||
'combine_consecutive_unsets' => true,
|
||||
'declare_strict_types' => true,
|
||||
'linebreak_after_opening_tag' => true,
|
||||
'lowercase_static_reference' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_unused_imports' => true,
|
||||
'not_operator_with_successor_space' => true,
|
||||
'not_operator_with_space' => false,
|
||||
'ordered_class_elements' => true,
|
||||
'php_unit_strict' => false,
|
||||
'phpdoc_separation' => false,
|
||||
'single_quote' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'multiline_comment_opening_closing' => true,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->exclude('vendor')
|
||||
->in(__DIR__)
|
||||
)
|
||||
->setUsingCache(false);
|
||||
6
addons/epay/library/hyperf/engine/.phpstorm.meta.php
Normal file
6
addons/epay/library/hyperf/engine/.phpstorm.meta.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace PHPSTORM_META {
|
||||
// Reflect
|
||||
override(\Psr\Container\ContainerInterface::get(0), map('@'));
|
||||
}
|
||||
46
addons/epay/library/hyperf/engine/Dockerfile
Normal file
46
addons/epay/library/hyperf/engine/Dockerfile
Normal file
@@ -0,0 +1,46 @@
|
||||
# Default Dockerfile
|
||||
#
|
||||
# @link https://www.hyperf.io
|
||||
# @document https://hyperf.wiki
|
||||
# @contact group@hyperf.io
|
||||
# @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
|
||||
ARG PHP_VERSION
|
||||
ARG ALPINE_VERSION
|
||||
|
||||
FROM hyperf/hyperf:${PHP_VERSION}-alpine-${ALPINE_VERSION}-swoole
|
||||
LABEL maintainer="Hyperf Developers <group@hyperf.io>" version="1.0" license="MIT" app.name="Hyperf"
|
||||
|
||||
ARG timezone
|
||||
ARG PHP_VERSION
|
||||
|
||||
ENV TIMEZONE=${timezone:-"Asia/Shanghai"}
|
||||
ENV COMPOSER_ROOT_VERSION="v1.2.0"
|
||||
|
||||
# update
|
||||
RUN set -ex \
|
||||
# show php version and extensions
|
||||
&& php -v \
|
||||
&& php -m \
|
||||
&& php --ri swoole \
|
||||
# ---------- some config ----------
|
||||
&& cd "/etc/php${PHP_VERSION%\.*}" \
|
||||
# - config PHP
|
||||
&& { \
|
||||
echo "upload_max_filesize=128M"; \
|
||||
echo "post_max_size=128M"; \
|
||||
echo "memory_limit=1G"; \
|
||||
echo "date.timezone=${TIMEZONE}"; \
|
||||
} | tee conf.d/99_overrides.ini \
|
||||
# - config timezone
|
||||
&& ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
|
||||
&& echo "${TIMEZONE}" > /etc/timezone \
|
||||
# ---------- clear works ----------
|
||||
&& rm -rf /var/cache/apk/* /tmp/* /usr/share/man \
|
||||
&& echo -e "\033[42;37m Build Completed :).\033[0m\n"
|
||||
|
||||
WORKDIR /opt/www
|
||||
|
||||
COPY . /opt/www
|
||||
|
||||
RUN composer install -o
|
||||
7
addons/epay/library/hyperf/engine/README.md
Normal file
7
addons/epay/library/hyperf/engine/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Swoole Engine
|
||||
|
||||

|
||||
|
||||
```
|
||||
composer require hyperf/engine
|
||||
```
|
||||
49
addons/epay/library/hyperf/engine/composer.json
Normal file
49
addons/epay/library/hyperf/engine/composer.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "hyperf/engine",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"php",
|
||||
"hyperf"
|
||||
],
|
||||
"description": "",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hyperf\\Engine\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"HyperfTest\\": "tests"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.0",
|
||||
"hyperf/guzzle": "^2.2",
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"phpunit/phpunit": "^9.4",
|
||||
"swoole/ide-helper": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-swoole": ">=4.5"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2-dev"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit -c phpunit.xml --colors=always",
|
||||
"analyse": "phpstan analyse --memory-limit 1024M -l 0 ./src",
|
||||
"cs-fix": "php-cs-fixer fix $1"
|
||||
}
|
||||
}
|
||||
15
addons/epay/library/hyperf/engine/phpunit.xml
Normal file
15
addons/epay/library/hyperf/engine/phpunit.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit bootstrap="tests/bootstrap.php"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
verbose="true"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
<testsuite name="Testsuite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</phpunit>
|
||||
142
addons/epay/library/hyperf/engine/src/Channel.php
Normal file
142
addons/epay/library/hyperf/engine/src/Channel.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine;
|
||||
|
||||
use Hyperf\Engine\Contract\ChannelInterface;
|
||||
use Hyperf\Engine\Exception\RuntimeException;
|
||||
|
||||
if (PHP_VERSION_ID > 80000 && SWOOLE_VERSION_ID >= 50000) {
|
||||
class Channel extends \Swoole\Coroutine\Channel implements ChannelInterface
|
||||
{
|
||||
protected bool $closed = false;
|
||||
|
||||
public function push(mixed $data, float $timeout = -1): bool
|
||||
{
|
||||
return parent::push($data, $timeout);
|
||||
}
|
||||
|
||||
public function pop(float $timeout = -1): mixed
|
||||
{
|
||||
return parent::pop($timeout);
|
||||
}
|
||||
|
||||
public function getCapacity(): int
|
||||
{
|
||||
return $this->capacity;
|
||||
}
|
||||
|
||||
public function getLength(): int
|
||||
{
|
||||
return $this->length();
|
||||
}
|
||||
|
||||
public function isAvailable(): bool
|
||||
{
|
||||
return ! $this->isClosing();
|
||||
}
|
||||
|
||||
public function close(): bool
|
||||
{
|
||||
$this->closed = true;
|
||||
return parent::close();
|
||||
}
|
||||
|
||||
public function hasProducers(): bool
|
||||
{
|
||||
throw new RuntimeException('Not supported.');
|
||||
}
|
||||
|
||||
public function hasConsumers(): bool
|
||||
{
|
||||
throw new RuntimeException('Not supported.');
|
||||
}
|
||||
|
||||
public function isReadable(): bool
|
||||
{
|
||||
throw new RuntimeException('Not supported.');
|
||||
}
|
||||
|
||||
public function isWritable(): bool
|
||||
{
|
||||
throw new RuntimeException('Not supported.');
|
||||
}
|
||||
|
||||
public function isClosing(): bool
|
||||
{
|
||||
return $this->closed || $this->errCode === SWOOLE_CHANNEL_CLOSED;
|
||||
}
|
||||
|
||||
public function isTimeout(): bool
|
||||
{
|
||||
return ! $this->closed && $this->errCode === SWOOLE_CHANNEL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
class Channel extends \Swoole\Coroutine\Channel implements ChannelInterface
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $closed = false;
|
||||
|
||||
public function getCapacity(): int
|
||||
{
|
||||
return $this->capacity;
|
||||
}
|
||||
|
||||
public function getLength(): int
|
||||
{
|
||||
return $this->length();
|
||||
}
|
||||
|
||||
public function isAvailable(): bool
|
||||
{
|
||||
return ! $this->isClosing();
|
||||
}
|
||||
|
||||
public function close(): bool
|
||||
{
|
||||
$this->closed = true;
|
||||
return parent::close();
|
||||
}
|
||||
|
||||
public function hasProducers(): bool
|
||||
{
|
||||
throw new RuntimeException('Not supported.');
|
||||
}
|
||||
|
||||
public function hasConsumers(): bool
|
||||
{
|
||||
throw new RuntimeException('Not supported.');
|
||||
}
|
||||
|
||||
public function isReadable(): bool
|
||||
{
|
||||
throw new RuntimeException('Not supported.');
|
||||
}
|
||||
|
||||
public function isWritable(): bool
|
||||
{
|
||||
throw new RuntimeException('Not supported.');
|
||||
}
|
||||
|
||||
public function isClosing(): bool
|
||||
{
|
||||
return $this->closed || $this->errCode === SWOOLE_CHANNEL_CLOSED;
|
||||
}
|
||||
|
||||
public function isTimeout(): bool
|
||||
{
|
||||
return ! $this->closed && $this->errCode === SWOOLE_CHANNEL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
addons/epay/library/hyperf/engine/src/Constant.php
Normal file
25
addons/epay/library/hyperf/engine/src/Constant.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine;
|
||||
|
||||
use Swoole\Coroutine\Http\Server as HttpServer;
|
||||
use Swoole\Coroutine\Server;
|
||||
|
||||
class Constant
|
||||
{
|
||||
public const ENGINE = 'Swoole';
|
||||
|
||||
public static function isCoroutineServer($server): bool
|
||||
{
|
||||
return $server instanceof Server || $server instanceof HttpServer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Contract;
|
||||
|
||||
if (PHP_VERSION_ID > 80000 && SWOOLE_VERSION_ID >= 50000) {
|
||||
interface ChannelInterface
|
||||
{
|
||||
/**
|
||||
* @param float|int $timeout [optional] = -1
|
||||
*/
|
||||
public function push(mixed $data, float $timeout = -1): bool;
|
||||
|
||||
/**
|
||||
* @param float $timeout seconds [optional] = -1
|
||||
* @return mixed when pop failed, return false
|
||||
*/
|
||||
public function pop(float $timeout = -1): mixed;
|
||||
|
||||
/**
|
||||
* Swow: When the channel is closed, all the data in it will be destroyed.
|
||||
* Swoole: When the channel is closed, the data in it can still be popped out, but push behavior will no longer succeed.
|
||||
*/
|
||||
public function close(): bool;
|
||||
|
||||
public function getCapacity(): int;
|
||||
|
||||
public function getLength(): int;
|
||||
|
||||
public function isAvailable(): bool;
|
||||
|
||||
public function hasProducers(): bool;
|
||||
|
||||
public function hasConsumers(): bool;
|
||||
|
||||
public function isEmpty(): bool;
|
||||
|
||||
public function isFull(): bool;
|
||||
|
||||
public function isReadable(): bool;
|
||||
|
||||
public function isWritable(): bool;
|
||||
|
||||
public function isClosing(): bool;
|
||||
|
||||
public function isTimeout(): bool;
|
||||
}
|
||||
} else {
|
||||
interface ChannelInterface
|
||||
{
|
||||
/**
|
||||
* @param mixed $data [required]
|
||||
* @param float|int $timeout [optional] = -1
|
||||
* @return bool
|
||||
*/
|
||||
public function push($data, $timeout = -1);
|
||||
|
||||
/**
|
||||
* @param float $timeout seconds [optional] = -1
|
||||
* @return mixed when pop failed, return false
|
||||
*/
|
||||
public function pop($timeout = -1);
|
||||
|
||||
/**
|
||||
* Swow: When the channel is closed, all the data in it will be destroyed.
|
||||
* Swoole: When the channel is closed, the data in it can still be popped out, but push behavior will no longer succeed.
|
||||
* @return mixed
|
||||
*/
|
||||
public function close(): bool;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCapacity();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLength();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAvailable();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasProducers();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasConsumers();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isFull();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWritable();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isClosing();
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTimeout();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Contract;
|
||||
|
||||
use Hyperf\Engine\Exception\CoroutineDestroyedException;
|
||||
use Hyperf\Engine\Exception\RunningInNonCoroutineException;
|
||||
|
||||
interface CoroutineInterface
|
||||
{
|
||||
/**
|
||||
* @param callable $callable [required]
|
||||
*/
|
||||
public function __construct(callable $callable);
|
||||
|
||||
/**
|
||||
* @param mixed ...$data
|
||||
* @return $this
|
||||
*/
|
||||
public function execute(...$data);
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId();
|
||||
|
||||
/**
|
||||
* @param callable $callable [required]
|
||||
* @param mixed ...$data
|
||||
* @return $this
|
||||
*/
|
||||
public static function create(callable $callable, ...$data);
|
||||
|
||||
/**
|
||||
* @return int returns coroutine id from current coroutine, -1 in non coroutine environment
|
||||
*/
|
||||
public static function id();
|
||||
|
||||
/**
|
||||
* Returns the parent coroutine ID.
|
||||
* Returns 0 when running in the top level coroutine.
|
||||
* @throws RunningInNonCoroutineException when running in non-coroutine context
|
||||
* @throws CoroutineDestroyedException when the coroutine has been destroyed
|
||||
*/
|
||||
public static function pid(?int $id = null);
|
||||
|
||||
/**
|
||||
* Set config to coroutine.
|
||||
*/
|
||||
public static function set(array $config);
|
||||
|
||||
/**
|
||||
* @param null|int $id coroutine id
|
||||
* @return null|\ArrayObject
|
||||
*/
|
||||
public static function getContextFor(?int $id = null);
|
||||
|
||||
/**
|
||||
* Execute callback when coroutine destruct.
|
||||
*/
|
||||
public static function defer(callable $callable);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Contract\Http;
|
||||
|
||||
use Hyperf\Engine\Http\RawResponse;
|
||||
|
||||
interface ClientInterface
|
||||
{
|
||||
public function set(array $settings): bool;
|
||||
|
||||
/**
|
||||
* @param string[][] $headers
|
||||
*/
|
||||
public function request(string $method = 'GET', string $path = '/', array $headers = [], string $contents = '', string $version = '1.1'): RawResponse;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Contract\WebSocket;
|
||||
|
||||
interface WebSocketInterface
|
||||
{
|
||||
public const ON_MESSAGE = 'message';
|
||||
|
||||
public const ON_CLOSE = 'close';
|
||||
|
||||
public function on(string $event, callable $callback): void;
|
||||
|
||||
public function start(): void;
|
||||
}
|
||||
100
addons/epay/library/hyperf/engine/src/Coroutine.php
Normal file
100
addons/epay/library/hyperf/engine/src/Coroutine.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine;
|
||||
|
||||
use Hyperf\Engine\Contract\CoroutineInterface;
|
||||
use Hyperf\Engine\Exception\CoroutineDestroyedException;
|
||||
use Hyperf\Engine\Exception\RunningInNonCoroutineException;
|
||||
use Hyperf\Engine\Exception\RuntimeException;
|
||||
use Swoole\Coroutine as SwooleCo;
|
||||
|
||||
class Coroutine implements CoroutineInterface
|
||||
{
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $callable;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $id;
|
||||
|
||||
public function __construct(callable $callable)
|
||||
{
|
||||
$this->callable = $callable;
|
||||
}
|
||||
|
||||
public static function create(callable $callable, ...$data)
|
||||
{
|
||||
$coroutine = new static($callable);
|
||||
$coroutine->execute(...$data);
|
||||
return $coroutine;
|
||||
}
|
||||
|
||||
public function execute(...$data)
|
||||
{
|
||||
$this->id = SwooleCo::create($this->callable, ...$data);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
if (is_null($this->id)) {
|
||||
throw new RuntimeException('Coroutine was not be executed.');
|
||||
}
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public static function id()
|
||||
{
|
||||
return SwooleCo::getCid();
|
||||
}
|
||||
|
||||
public static function pid(?int $id = null)
|
||||
{
|
||||
if ($id) {
|
||||
$cid = SwooleCo::getPcid($id);
|
||||
if ($cid === false) {
|
||||
throw new CoroutineDestroyedException(sprintf('Coroutine #%d has been destroyed.', $id));
|
||||
}
|
||||
} else {
|
||||
$cid = SwooleCo::getPcid();
|
||||
}
|
||||
if ($cid === false) {
|
||||
throw new RunningInNonCoroutineException('Non-Coroutine environment don\'t has parent coroutine id.');
|
||||
}
|
||||
return max(0, $cid);
|
||||
}
|
||||
|
||||
public static function set(array $config)
|
||||
{
|
||||
SwooleCo::set($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|\ArrayObject
|
||||
*/
|
||||
public static function getContextFor(?int $id = null)
|
||||
{
|
||||
if ($id === null) {
|
||||
return SwooleCo::getContext();
|
||||
}
|
||||
|
||||
return SwooleCo::getContext($id);
|
||||
}
|
||||
|
||||
public static function defer(callable $callable)
|
||||
{
|
||||
SwooleCo::defer($callable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Exception;
|
||||
|
||||
class CoroutineDestroyedException extends RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Exception;
|
||||
|
||||
class HttpClientException extends RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Exception;
|
||||
|
||||
class RunningInNonCoroutineException extends RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Exception;
|
||||
|
||||
class RuntimeException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
20
addons/epay/library/hyperf/engine/src/Extension.php
Normal file
20
addons/epay/library/hyperf/engine/src/Extension.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine;
|
||||
|
||||
class Extension
|
||||
{
|
||||
public static function isLoaded(): bool
|
||||
{
|
||||
return extension_loaded('Swoole');
|
||||
}
|
||||
}
|
||||
76
addons/epay/library/hyperf/engine/src/Http/Client.php
Normal file
76
addons/epay/library/hyperf/engine/src/Http/Client.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Http;
|
||||
|
||||
use Hyperf\Engine\Contract\Http\ClientInterface;
|
||||
use Hyperf\Engine\Exception\HttpClientException;
|
||||
use Swoole\Coroutine\Http\Client as HttpClient;
|
||||
|
||||
class Client extends HttpClient implements ClientInterface
|
||||
{
|
||||
public function set(array $settings): bool
|
||||
{
|
||||
return parent::set($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[][] $headers
|
||||
*/
|
||||
public function request(string $method = 'GET', string $path = '/', array $headers = [], string $contents = '', string $version = '1.1'): RawResponse
|
||||
{
|
||||
$this->setMethod($method);
|
||||
$this->setData($contents);
|
||||
$this->setHeaders($this->encodeHeaders($headers));
|
||||
$this->execute($path);
|
||||
if ($this->errCode !== 0) {
|
||||
throw new HttpClientException($this->errMsg, $this->errCode);
|
||||
}
|
||||
return new RawResponse(
|
||||
$this->statusCode,
|
||||
$this->decodeHeaders($this->headers ?? []),
|
||||
$this->body,
|
||||
$version
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $headers
|
||||
* @return string[][]
|
||||
*/
|
||||
private function decodeHeaders(array $headers): array
|
||||
{
|
||||
$result = [];
|
||||
foreach ($headers as $name => $header) {
|
||||
// The key of header is lower case.
|
||||
$result[$name][] = $header;
|
||||
}
|
||||
if ($this->set_cookie_headers) {
|
||||
$result['set-cookie'] = $this->set_cookie_headers;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swoole engine not support two dimensional array.
|
||||
* @param string[][] $headers
|
||||
* @return string[]
|
||||
*/
|
||||
private function encodeHeaders(array $headers): array
|
||||
{
|
||||
$result = [];
|
||||
foreach ($headers as $name => $value) {
|
||||
$result[$name] = is_array($value) ? implode(',', $value) : $value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
22
addons/epay/library/hyperf/engine/src/Http/FdGetter.php
Normal file
22
addons/epay/library/hyperf/engine/src/Http/FdGetter.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Http;
|
||||
|
||||
use Swoole\Http\Response;
|
||||
|
||||
class FdGetter
|
||||
{
|
||||
public function get(Response $response): int
|
||||
{
|
||||
return $response->fd;
|
||||
}
|
||||
}
|
||||
47
addons/epay/library/hyperf/engine/src/Http/RawResponse.php
Normal file
47
addons/epay/library/hyperf/engine/src/Http/RawResponse.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\Http;
|
||||
|
||||
final class RawResponse
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $statusCode = 0;
|
||||
|
||||
/**
|
||||
* @var string[][]
|
||||
*/
|
||||
public $headers = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $body = '';
|
||||
|
||||
/**
|
||||
* Protocol version.
|
||||
* @var string
|
||||
*/
|
||||
public $version = '';
|
||||
|
||||
/**
|
||||
* @param string[][] $headers
|
||||
*/
|
||||
public function __construct(int $statusCode, array $headers, string $body, string $version)
|
||||
{
|
||||
$this->statusCode = $statusCode;
|
||||
$this->headers = $headers;
|
||||
$this->body = $body;
|
||||
$this->version = $version;
|
||||
}
|
||||
}
|
||||
16
addons/epay/library/hyperf/engine/src/Socket.php
Normal file
16
addons/epay/library/hyperf/engine/src/Socket.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine;
|
||||
|
||||
class Socket extends \Swoole\Coroutine\Socket
|
||||
{
|
||||
}
|
||||
16
addons/epay/library/hyperf/engine/src/WaitGroup.php
Normal file
16
addons/epay/library/hyperf/engine/src/WaitGroup.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine;
|
||||
|
||||
class WaitGroup extends \Swoole\Coroutine\WaitGroup
|
||||
{
|
||||
}
|
||||
19
addons/epay/library/hyperf/engine/src/WebSocket/Frame.php
Normal file
19
addons/epay/library/hyperf/engine/src/WebSocket/Frame.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\WebSocket;
|
||||
|
||||
class Frame
|
||||
{
|
||||
public const PING = '27890027';
|
||||
|
||||
public const PONG = '278a0027';
|
||||
}
|
||||
27
addons/epay/library/hyperf/engine/src/WebSocket/Opcode.php
Normal file
27
addons/epay/library/hyperf/engine/src/WebSocket/Opcode.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\WebSocket;
|
||||
|
||||
class Opcode
|
||||
{
|
||||
public const CONTINUATION = 0;
|
||||
|
||||
public const TEXT = 1;
|
||||
|
||||
public const BINARY = 2;
|
||||
|
||||
public const CLOSE = 8;
|
||||
|
||||
public const PING = 9;
|
||||
|
||||
public const PONG = 10;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Engine\WebSocket;
|
||||
|
||||
use Hyperf\Engine\Contract\WebSocket\WebSocketInterface;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\WebSocket\CloseFrame;
|
||||
|
||||
class WebSocket implements WebSocketInterface
|
||||
{
|
||||
/**
|
||||
* @var Response
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var array<string, callable>
|
||||
*/
|
||||
protected $events = [];
|
||||
|
||||
public function __construct(Response $connection, Request $request)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->connection->upgrade();
|
||||
}
|
||||
|
||||
public function on(string $event, callable $callback): void
|
||||
{
|
||||
$this->events[$event] = $callback;
|
||||
}
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
while (true) {
|
||||
$frame = $this->connection->recv();
|
||||
if ($frame === false || $frame instanceof CloseFrame || $frame === '') {
|
||||
$callback = $this->events[static::ON_CLOSE];
|
||||
$callback($this->connection, $this->connection->fd);
|
||||
break;
|
||||
}
|
||||
|
||||
$callback = $this->events[static::ON_MESSAGE];
|
||||
$callback($this->connection, $frame);
|
||||
}
|
||||
|
||||
$this->connection = null;
|
||||
$this->events = [];
|
||||
}
|
||||
}
|
||||
2
addons/epay/library/hyperf/macroable/.gitattributes
vendored
Normal file
2
addons/epay/library/hyperf/macroable/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/tests export-ignore
|
||||
/.github export-ignore
|
||||
22
addons/epay/library/hyperf/macroable/LICENSE
Normal file
22
addons/epay/library/hyperf/macroable/LICENSE
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Taylor Otwell
|
||||
Copyright (c) Hyperf
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
39
addons/epay/library/hyperf/macroable/composer.json
Normal file
39
addons/epay/library/hyperf/macroable/composer.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "hyperf/macroable",
|
||||
"description": "Hyperf Macroable package which come from illuminate/macroable",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"php",
|
||||
"swoole",
|
||||
"hyperf",
|
||||
"macroable"
|
||||
],
|
||||
"homepage": "https://hyperf.io",
|
||||
"support": {
|
||||
"docs": "https://hyperf.wiki",
|
||||
"issues": "https://github.com/hyperf/hyperf/issues",
|
||||
"pull-request": "https://github.com/hyperf/hyperf/pulls",
|
||||
"source": "https://github.com/hyperf/hyperf"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hyperf\\Macroable\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"HyperfTest\\Macroable\\": "tests/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
129
addons/epay/library/hyperf/macroable/src/Macroable.php
Normal file
129
addons/epay/library/hyperf/macroable/src/Macroable.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Macroable;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Closure;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* This file come from illuminate/macroable,
|
||||
* thanks Laravel Team provide such a useful class.
|
||||
*/
|
||||
trait Macroable
|
||||
{
|
||||
/**
|
||||
* The registered string macros.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $macros = [];
|
||||
|
||||
/**
|
||||
* Dynamically handle calls to the class.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @throws \BadMethodCallException
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
if (! static::hasMacro($method)) {
|
||||
throw new BadMethodCallException(sprintf(
|
||||
'Method %s::%s does not exist.',
|
||||
static::class,
|
||||
$method
|
||||
));
|
||||
}
|
||||
|
||||
$macro = static::$macros[$method];
|
||||
|
||||
if ($macro instanceof Closure) {
|
||||
$macro = $macro->bindTo(null, static::class);
|
||||
}
|
||||
|
||||
return $macro(...$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically handle calls to the class.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @throws \BadMethodCallException
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
if (! static::hasMacro($method)) {
|
||||
throw new BadMethodCallException(sprintf(
|
||||
'Method %s::%s does not exist.',
|
||||
static::class,
|
||||
$method
|
||||
));
|
||||
}
|
||||
|
||||
$macro = static::$macros[$method];
|
||||
|
||||
if ($macro instanceof Closure) {
|
||||
$macro = $macro->bindTo($this, static::class);
|
||||
}
|
||||
|
||||
return $macro(...$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom macro.
|
||||
*
|
||||
* @param string $name
|
||||
* @param callable|object $macro
|
||||
*/
|
||||
public static function macro($name, $macro)
|
||||
{
|
||||
static::$macros[$name] = $macro;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix another object into the class.
|
||||
*
|
||||
* @param object $mixin
|
||||
* @param bool $replace
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function mixin($mixin, $replace = true)
|
||||
{
|
||||
$methods = (new ReflectionClass($mixin))->getMethods(
|
||||
ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
|
||||
);
|
||||
|
||||
foreach ($methods as $method) {
|
||||
if ($replace || ! static::hasMacro($method->name)) {
|
||||
$method->setAccessible(true);
|
||||
static::macro($method->name, $method->invoke($mixin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if macro is registered.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasMacro($name)
|
||||
{
|
||||
return isset(static::$macros[$name]);
|
||||
}
|
||||
}
|
||||
2
addons/epay/library/hyperf/pimple/.gitattributes
vendored
Normal file
2
addons/epay/library/hyperf/pimple/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/tests export-ignore
|
||||
/.github export-ignore
|
||||
4
addons/epay/library/hyperf/pimple/.gitignore
vendored
Normal file
4
addons/epay/library/hyperf/pimple/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/vendor/
|
||||
composer.lock
|
||||
*.cache
|
||||
*.log
|
||||
92
addons/epay/library/hyperf/pimple/.php-cs-fixer.php
Normal file
92
addons/epay/library/hyperf/pimple/.php-cs-fixer.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
$header = <<<'EOF'
|
||||
This file is part of Hyperf.
|
||||
|
||||
@link https://www.hyperf.io
|
||||
@document https://hyperf.wiki
|
||||
@contact group@hyperf.io
|
||||
@license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
EOF;
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'@Symfony' => true,
|
||||
'@DoctrineAnnotation' => true,
|
||||
'@PhpCsFixer' => true,
|
||||
'header_comment' => [
|
||||
'comment_type' => 'PHPDoc',
|
||||
'header' => $header,
|
||||
'separate' => 'none',
|
||||
'location' => 'after_declare_strict',
|
||||
],
|
||||
'array_syntax' => [
|
||||
'syntax' => 'short'
|
||||
],
|
||||
'list_syntax' => [
|
||||
'syntax' => 'short'
|
||||
],
|
||||
'concat_space' => [
|
||||
'spacing' => 'one'
|
||||
],
|
||||
'blank_line_before_statement' => [
|
||||
'statements' => [
|
||||
'declare',
|
||||
],
|
||||
],
|
||||
'general_phpdoc_annotation_remove' => [
|
||||
'annotations' => [
|
||||
'author'
|
||||
],
|
||||
],
|
||||
'ordered_imports' => [
|
||||
'imports_order' => [
|
||||
'class', 'function', 'const',
|
||||
],
|
||||
'sort_algorithm' => 'alpha',
|
||||
],
|
||||
'single_line_comment_style' => [
|
||||
'comment_types' => [
|
||||
],
|
||||
],
|
||||
'yoda_style' => [
|
||||
'always_move_variable' => false,
|
||||
'equal' => false,
|
||||
'identical' => false,
|
||||
],
|
||||
'phpdoc_align' => [
|
||||
'align' => 'left',
|
||||
],
|
||||
'multiline_whitespace_before_semicolons' => [
|
||||
'strategy' => 'no_multi_line',
|
||||
],
|
||||
'constant_case' => [
|
||||
'case' => 'lower',
|
||||
],
|
||||
'class_attributes_separation' => true,
|
||||
'combine_consecutive_unsets' => true,
|
||||
'declare_strict_types' => true,
|
||||
'linebreak_after_opening_tag' => true,
|
||||
'lowercase_static_reference' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_unused_imports' => true,
|
||||
'not_operator_with_successor_space' => true,
|
||||
'not_operator_with_space' => false,
|
||||
'ordered_class_elements' => true,
|
||||
'php_unit_strict' => false,
|
||||
'phpdoc_separation' => false,
|
||||
'single_quote' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'multiline_comment_opening_closing' => true,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->exclude('bin')
|
||||
->exclude('public')
|
||||
->exclude('runtime')
|
||||
->exclude('vendor')
|
||||
->in(__DIR__)
|
||||
)
|
||||
->setUsingCache(false);
|
||||
6
addons/epay/library/hyperf/pimple/.phpstorm.meta.php
Normal file
6
addons/epay/library/hyperf/pimple/.phpstorm.meta.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace PHPSTORM_META {
|
||||
// Reflect
|
||||
override(\Psr\Container\ContainerInterface::get(0), map('@'));
|
||||
}
|
||||
42
addons/epay/library/hyperf/pimple/.travis.yml
Normal file
42
addons/epay/library/hyperf/pimple/.travis.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
language: php
|
||||
|
||||
sudo: required
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 7.2
|
||||
env: SW_VERSION="4.4.17"
|
||||
- php: 7.3
|
||||
env: SW_VERSION="4.4.17"
|
||||
- php: 7.4
|
||||
env: SW_VERSION="4.4.17"
|
||||
- php: master
|
||||
env: SW_VERSION="4.4.17"
|
||||
|
||||
allow_failures:
|
||||
- php: master
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- redis-server
|
||||
- docker
|
||||
|
||||
before_install:
|
||||
- export PHP_MAJOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 1)"
|
||||
- export PHP_MINOR="$(`phpenv which php` -r 'echo phpversion();' | cut -d '.' -f 2)"
|
||||
- echo $PHP_MAJOR
|
||||
- echo $PHP_MINOR
|
||||
|
||||
install:
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- bash ./tests/swoole.install.sh
|
||||
- phpenv config-rm xdebug.ini || echo "xdebug not available"
|
||||
- phpenv config-add ./tests/ci.ini
|
||||
|
||||
before_script:
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- composer config -g process-timeout 900 && composer update
|
||||
|
||||
script:
|
||||
- composer analyse
|
||||
- composer test
|
||||
195
addons/epay/library/hyperf/pimple/README.md
Normal file
195
addons/epay/library/hyperf/pimple/README.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# Pimple Container
|
||||
|
||||
[](https://travis-ci.org/hyperf-cloud/pimple-integration)
|
||||
|
||||
`hyperf/pimple` 是基于 `pimple/pimple` 实现的轻量级符合 `PSR11 规范` 的容器组件。可以减少其他框架使用 Hyperf 组件时的成本。
|
||||
|
||||
## 安装
|
||||
|
||||
```
|
||||
composer require "hyperf/pimple:1.1.*"
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Hyperf\Pimple\ContainerFactory;
|
||||
|
||||
$container = (new ContainerFactory())();
|
||||
|
||||
```
|
||||
|
||||
### `EasySwoole` 接入 `hyperf/translation`
|
||||
|
||||
因为 `EasySwoole` 的容器组件暂时并没有实现 `PSR11` 规范,所以无法直接使用。
|
||||
|
||||
1. 首先引入相关组件
|
||||
|
||||
```
|
||||
composer require "hyperf/translation:1.1.*"
|
||||
composer require "hyperf/config:1.1.*"
|
||||
```
|
||||
|
||||
2. 添加 国际化相关的 Provider
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Provider;
|
||||
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Contract\ContainerInterface;
|
||||
use Hyperf\Contract\TranslatorLoaderInterface;
|
||||
use Hyperf\Pimple\ProviderInterface;
|
||||
use Hyperf\Translation\FileLoader;
|
||||
use Hyperf\Utils\Filesystem\Filesystem;
|
||||
|
||||
class TranslatorLoaderProvider implements ProviderInterface
|
||||
{
|
||||
public function register(ContainerInterface $container)
|
||||
{
|
||||
$container->set(TranslatorLoaderInterface::class, function () use ($container) {
|
||||
$config = $container->get(ConfigInterface::class);
|
||||
$files = $container->get(Filesystem::class);
|
||||
$path = $config->get('translation.path');
|
||||
|
||||
return make(FileLoader::class, compact('files', 'path'));
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Provider;
|
||||
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Contract\ContainerInterface;
|
||||
use Hyperf\Contract\TranslatorInterface;
|
||||
use Hyperf\Contract\TranslatorLoaderInterface;
|
||||
use Hyperf\Pimple\ProviderInterface;
|
||||
use Hyperf\Translation\Translator;
|
||||
|
||||
class TranslatorProvider implements ProviderInterface
|
||||
{
|
||||
public function register(ContainerInterface $container)
|
||||
{
|
||||
$container->set(TranslatorInterface::class, function () use ($container) {
|
||||
$config = $container->get(ConfigInterface::class);
|
||||
$locale = $config->get('translation.locale');
|
||||
$fallbackLocale = $config->get('translation.fallback_locale');
|
||||
|
||||
$loader = $container->get(TranslatorLoaderInterface::class);
|
||||
|
||||
$translator = make(Translator::class, compact('loader', 'locale'));
|
||||
$translator->setFallback((string) $fallbackLocale);
|
||||
|
||||
return $translator;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
3. `EasySwoole` 事件注册器在 `EasySwooleEvent.php` 中,所以我们需要在 `initialize()` 中初始化我们的容器和国际化组件。
|
||||
|
||||
> 以下 Config 组件,可以自行封装,这里方便起见直接配置。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace EasySwoole\EasySwoole;
|
||||
|
||||
use EasySwoole\EasySwoole\AbstractInterface\Event;
|
||||
use EasySwoole\EasySwoole\Swoole\EventRegister;
|
||||
use EasySwoole\Http\Request;
|
||||
use EasySwoole\Http\Response;
|
||||
use Hyperf\Config\Config;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Pimple\ContainerFactory;
|
||||
use App\Provider\TranslatorProvider;
|
||||
use App\Provider\TranslatorLoaderProvider;
|
||||
|
||||
class EasySwooleEvent implements Event
|
||||
{
|
||||
public static function initialize()
|
||||
{
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
$container = (new ContainerFactory([
|
||||
TranslatorProvider::class,
|
||||
TranslatorLoaderProvider::class,
|
||||
]))();
|
||||
$container->set(ConfigInterface::class, new Config([
|
||||
'translation' => [
|
||||
'locale' => 'zh_CN',
|
||||
'fallback_locale' => 'en',
|
||||
'path' => EASYSWOOLE_ROOT . '/storage/languages',
|
||||
],
|
||||
]));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. 修改控制器,使用国际化组件
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\HttpController;
|
||||
|
||||
use EasySwoole\Http\AbstractInterface\Controller;
|
||||
use Hyperf\Contract\TranslatorInterface;
|
||||
use Hyperf\Utils\ApplicationContext;
|
||||
use Hyperf\Utils\Codec\Json;
|
||||
|
||||
class Index extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$container = ApplicationContext::getContainer();
|
||||
$translator = $container->get(TranslatorInterface::class);
|
||||
|
||||
$data = [
|
||||
'message' => $translator->trans('message.hello', ['name' => 'Hyperf']),
|
||||
];
|
||||
|
||||
$this->response()->write(Json::encode($data));
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
5. 添加国际化配置
|
||||
|
||||
```php
|
||||
// storage/languages/en/message.php
|
||||
return [
|
||||
'hello' => 'Hello :name',
|
||||
];
|
||||
|
||||
// storage/languages/zh_CN/message.php
|
||||
return [
|
||||
'hello' => '你好 :name',
|
||||
];
|
||||
```
|
||||
|
||||
6. 测试
|
||||
|
||||
```
|
||||
$ curl http://127.0.0.1:9501/
|
||||
{"message":"你好 Hyperf"}
|
||||
```
|
||||
|
||||
|
||||
|
||||
53
addons/epay/library/hyperf/pimple/composer.json
Normal file
53
addons/epay/library/hyperf/pimple/composer.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "hyperf/pimple",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"php",
|
||||
"hyperf",
|
||||
"container",
|
||||
"psr11"
|
||||
],
|
||||
"description": "Pimple Container",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hyperf\\Pimple\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"HyperfTest\\": "tests"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"doctrine/instantiator": "^1.0",
|
||||
"hyperf/utils": "^2.2|^3.0",
|
||||
"pimple/pimple": "^3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.0",
|
||||
"mockery/mockery": "^1.3",
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"phpunit/phpunit": ">=7.0"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit -c phpunit.xml --colors=always",
|
||||
"analyse": "phpstan analyse --memory-limit 300M -l 0 ./src",
|
||||
"cs-fix": "php-cs-fixer fix $1"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
},
|
||||
"hyperf": {
|
||||
"config": "Hyperf\\Pimple\\ConfigProvider"
|
||||
}
|
||||
}
|
||||
}
|
||||
15
addons/epay/library/hyperf/pimple/phpunit.xml
Normal file
15
addons/epay/library/hyperf/pimple/phpunit.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit bootstrap="tests/bootstrap.php"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
verbose="true"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
<testsuite name="Testsuite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</phpunit>
|
||||
32
addons/epay/library/hyperf/pimple/src/ConfigProvider.php
Normal file
32
addons/epay/library/hyperf/pimple/src/ConfigProvider.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Pimple;
|
||||
|
||||
class ConfigProvider
|
||||
{
|
||||
public function __invoke(): array
|
||||
{
|
||||
return [
|
||||
'dependencies' => [
|
||||
],
|
||||
'commands' => [
|
||||
],
|
||||
'annotations' => [
|
||||
'scan' => [
|
||||
'paths' => [
|
||||
__DIR__,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
139
addons/epay/library/hyperf/pimple/src/Container.php
Normal file
139
addons/epay/library/hyperf/pimple/src/Container.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Pimple;
|
||||
|
||||
use Hyperf\Contract\ContainerInterface;
|
||||
use Hyperf\Pimple\Exception\InvalidDefinitionException;
|
||||
use Hyperf\Pimple\Exception\NotFoundException;
|
||||
use Hyperf\Pimple\Exception\NotSupportException;
|
||||
use Pimple;
|
||||
use Psr\Container\ContainerInterface as PsrContainerInterface;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use ReflectionMethod;
|
||||
use ReflectionParameter;
|
||||
|
||||
class Container implements ContainerInterface
|
||||
{
|
||||
/**
|
||||
* @var Pimple\Container
|
||||
*/
|
||||
protected $pimple;
|
||||
|
||||
/**
|
||||
* @var ReflectionClass[]
|
||||
*/
|
||||
protected $reflection = [];
|
||||
|
||||
public function __construct(Pimple\Container $pimple)
|
||||
{
|
||||
$this->pimple = $pimple;
|
||||
$this->pimple[ContainerInterface::class] = $this;
|
||||
$this->pimple[PsrContainerInterface::class] = $this;
|
||||
}
|
||||
|
||||
public function get($id)
|
||||
{
|
||||
if ($this->has($id)) {
|
||||
return $this->pimple[$id];
|
||||
}
|
||||
|
||||
return $this->pimple[$id] = $this->make($id);
|
||||
}
|
||||
|
||||
public function has($id): bool
|
||||
{
|
||||
return isset($this->pimple[$id]);
|
||||
}
|
||||
|
||||
public function make(string $name, array $parameters = [])
|
||||
{
|
||||
if (! class_exists($name)) {
|
||||
throw new NotFoundException("Entry {$name} is not found.");
|
||||
}
|
||||
|
||||
$ref = $this->reflection[$name] ?? new ReflectionClass($name);
|
||||
$constructor = $ref->getConstructor();
|
||||
$args = [];
|
||||
if ($constructor && $constructor->isPublic()) {
|
||||
$args = $this->resolveParameters($constructor, $parameters);
|
||||
}
|
||||
|
||||
$instance = new $name(...$args);
|
||||
|
||||
$this->reflection[$name] = $ref;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
public function set(string $name, $entry): void
|
||||
{
|
||||
$this->pimple[$name] = $entry;
|
||||
}
|
||||
|
||||
public function define(string $name, $definition): void
|
||||
{
|
||||
throw new NotSupportException('Method define is not support.');
|
||||
}
|
||||
|
||||
public function unbind(string $name): void
|
||||
{
|
||||
$this->pimple[$name] = null;
|
||||
}
|
||||
|
||||
protected function resolveParameters(ReflectionMethod $method, $parameters = [])
|
||||
{
|
||||
$args = [];
|
||||
foreach ($method->getParameters() as $index => $parameter) {
|
||||
if (array_key_exists($parameter->getName(), $parameters)) {
|
||||
$value = $parameters[$parameter->getName()];
|
||||
} elseif (array_key_exists($index, $parameters)) {
|
||||
$value = $parameters[$index];
|
||||
} elseif ($parameter->getType() && $this->has($parameter->getType()->getName())) {
|
||||
$value = $this->get($parameter->getType()->getName());
|
||||
} else {
|
||||
if ($parameter->isDefaultValueAvailable() || $parameter->isOptional()) {
|
||||
$value = $this->getParameterDefaultValue($parameter, $method);
|
||||
} else {
|
||||
throw new InvalidDefinitionException(sprintf(
|
||||
'Parameter $%s of %s has no value defined or guessable',
|
||||
$parameter->getName(),
|
||||
$this->getFunctionName($method)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$args[] = $value;
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
protected function getParameterDefaultValue(ReflectionParameter $parameter, ReflectionMethod $function)
|
||||
{
|
||||
try {
|
||||
return $parameter->getDefaultValue();
|
||||
} catch (ReflectionException $e) {
|
||||
throw new InvalidDefinitionException(sprintf(
|
||||
'The parameter "%s" of %s has no type defined or guessable. It has a default value, '
|
||||
. 'but the default value can\'t be read through Reflection because it is a PHP internal class.',
|
||||
$parameter->getName(),
|
||||
$this->getFunctionName($function)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private function getFunctionName(ReflectionMethod $method): string
|
||||
{
|
||||
return $method->getName() . '()';
|
||||
}
|
||||
}
|
||||
37
addons/epay/library/hyperf/pimple/src/ContainerFactory.php
Normal file
37
addons/epay/library/hyperf/pimple/src/ContainerFactory.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Pimple;
|
||||
|
||||
use Hyperf\Utils\ApplicationContext;
|
||||
use Pimple;
|
||||
|
||||
class ContainerFactory
|
||||
{
|
||||
protected $providers = [];
|
||||
|
||||
public function __construct(array $providers = [])
|
||||
{
|
||||
$this->providers = $providers;
|
||||
}
|
||||
|
||||
public function __invoke()
|
||||
{
|
||||
$container = new Container(new Pimple\Container());
|
||||
foreach ($this->providers as $provider) {
|
||||
/** @var ProviderInterface $instance */
|
||||
$instance = new $provider();
|
||||
$instance->register($container);
|
||||
}
|
||||
|
||||
return ApplicationContext::setContainer($container);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Pimple\Exception;
|
||||
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
|
||||
class InvalidDefinitionException extends \Exception implements ContainerExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Pimple\Exception;
|
||||
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class NotFoundException extends \RuntimeException implements NotFoundExceptionInterface
|
||||
{
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user