This commit is contained in:
leafrainy 2022-06-07 10:06:10 +08:00
parent 46a8583dc3
commit 8df8af7108
13002 changed files with 1515777 additions and 0 deletions

BIN
web/.DS_Store vendored Normal file

Binary file not shown.

BIN
web/PhalApi/.DS_Store vendored Normal file

Binary file not shown.

36
web/PhalApi/composer.json Normal file
View File

@ -0,0 +1,36 @@
{
"name": "phalapi/phalapi",
"description": "PhalApi v2.x一个PHP轻量级开源接口框架致力于快速开发接口服务。",
"type": "project",
"keywords": ["api"],
"homepage": "http://www.phalapi.net",
"license" : "GPL-3.0+",
"minimum-stability": "dev",
"authors": [
{
"name": "Dogstar Huang",
"email": "chanzonghuang@gmail.com",
"homepage" : "http://my.oschina.net/dogstar",
"role": "Developer"
}
],
"require": {
"php": ">=5.3.3",
"phalapi/kernal": "2.*.*",
"phalapi/qrcode": "dev-master",
"phalapi/cli": "dev-master",
"phalapi/task": "dev-master",
"phalapi/qiniu": "dev-master",
"phalapi/phpmailer":"dev-master"
},
"autoload": {
"files": [
"src/app/functions.php",
"src/app/redis.php"
],
"psr-4": {
"App\\": "src/app"
}
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* 请在下面放置任何您需要的应用配置
*
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2017-07-13
*/
return array(
/**
* 应用接口层的统一参数
*/
'apiCommonRules' => array(
'uid' => array('name' => 'uid', 'type' => 'int', 'default'=>'0', 'desc' => '用户id'),
'token' => array('name' => 'token', 'type' => 'string', 'default'=>'', 'desc' => '用户token'),
'model' => array('name' => 'model', 'type' => 'string', 'default'=>'', 'desc' => '手机型号'),
'system' => array('name' => 'system', 'type' => 'string', 'default'=>'', 'desc' => '系统'),
'version' => array('name' => 'version', 'type' => 'string', 'default'=>'', 'desc' => '版本'),
'lang' => array('name' => 'lang', 'type' => 'string', 'default'=>'', 'desc' => '语言'),
),
/* redis信息 */
'REDIS_HOST' => "127.0.0.1",
'REDIS_AUTH' => "",
'REDIS_PORT' => "",
/* 接口签名key */
'sign_key' => '400d069a791d51ada8af3e6c2979bcd7',
/* 存储方式 0本地 1七牛;2:亚马逊*/
'uptype' => "2",
/**
* 七牛相关配置
*/
'Qiniu' => array(
//ak
'access_key' => '',
//sk
'secret_key' => '',
//存储空间
'space_bucket' => '',
//cdn加速域名 格式http(s)://a.com
'space_host' => '',
// 上传文件名前缀
'preffix' => '',
'region'=>'z0',
//区域上传域名(服务端) https://developer.qiniu.com/kodo/manual/1671/region-endpoint 非华东需配置
//'upload_url' => '',
),
'Aws' => array(
'space_host' => 'https://x.amazonaws.com', // 如果有配置此项,则优先使用此域名
),
/**
* 接口服务白名单,格式:接口服务类名.接口服务方法名
*
* 示例:
* - *.* 通配,全部接口服务,慎用!
* - Site.* Api_Default接口类的全部方法
* - *.Index 全部接口类的Index方法
* - Site.Index 指定某个接口服务即Api_Default::Index()
*/
'service_whitelist' => array(
'Site.Index',
),
);

View File

@ -0,0 +1,68 @@
<?php return array (
'ios'=>array(
'codingmode' => '2', //编码 0自动1软编2硬编
'resolution' => '3', //分辨率-->3:360X640 ,4: 540X960 ,5:720X1280 分辨率修改时,码率也许对应调整
'isauto' => '1', //是否自适应 0否1是
'fps' => '20', //帧数
'fps_min' => '20', //最低帧数
'fps_max' => '30', //最高帧数
'gop' => '3', //关键帧间隔
'bitrate' => '400', //初始码率 kbps
'bitrate_min' => '400', //最低码率
'bitrate_max' => '800', //最高码率 //最高分辨是 码率为:1000
'audiorate' => '44100', //音频采样率 Hz
'audiobitrate' => '48', //音频码率 kbps
'preview_fps' => '15', //预览帧数
'preview_resolution' => '1', //预览分辨率
),
'android_tx'=>array( //腾讯sdk安卓端使用
'codingmode' => '3', //编码 1自动3软编2硬编
'resolution' => '1', //分辨率
'isauto' => '1', //是否自适应 0否1是
'fps' => '15', //帧数
'fps_min' => '20', //最低帧数
'fps_max' => '30', //最高帧数
'gop' => '1', //关键帧间隔
'bitrate' => '1200', //初始码率 kbps //最高分辨是 码率为:2400
'bitrate_min' => '800', //最低码率 //最高分辨是 码率为:1600
'bitrate_max' => '1500', //最高码率 //最高分辨是 码率为:3000
'audiorate' => '48000', //音频采样率 Hz
//'audiobitrate' => '48', //音频码率 kbps
'preview_fps' => '15', //预览帧数
'preview_resolution' => '1', //预览分辨率
),
/*
安卓分辨率 - 腾讯云
0 => 360_640 ;
1 => 540_960 ;
2 => 720_1280 ;
3 => 640_360 ;
4 => 960_540 ;
5 => 1280_720 ;
6 => 320_480 ;
7 => 180_320 ;
8 => 270_480 ;
9 => 320_180 ;
10 => 480_270 ;
11 => 240_320 ;
12 => 360_480 ;
13 => 480_640 ;
14 => 320_240 ;
15 => 480_360 ;
16 => 640_480 ;
17 => 480_480 ;
18 => 270_270 ;
19 => 160_160 ;
30 => 1080_1920 ;
31 => 1920_1080 ;
*/
);

View File

@ -0,0 +1,374 @@
{
"comment":["以下内容用于App同城功能,获取城市列表"],
"country":[
{
"title":"A",
"lists":[
{"name":"阿尔巴尼亚","name_en":"Albania","tel":"355"},
{"name":"阿尔及利亚","name_en":"Algeria","tel":"213"},
{"name":"阿富汗","name_en":"Afghanistan","tel":"93"},
{"name":"阿根廷","name_en":"Argentina","tel":"54"},
{"name":"阿拉伯联合酋长国","name_en":"UnitedArabEmirates","tel":"971"},
{"name":"阿曼","name_en":"Oman","tel":"968"},
{"name":"阿美尼亚","name_en":"Armenia","tel":"374"},
{"name":"阿塞拜疆","name_en":"Azerbaijan","tel":"994"},
{"name":"爱尔兰","name_en":"Ireland","tel":"353"},
{"name":"埃及","name_en":"Egypt","tel":"20"},
{"name":"埃塞俄比亚","name_en":"Ethiopia","tel":"251"},
{"name":"爱沙尼亚","name_en":"Estonia","tel":"372"},
{"name":"澳大利亚","name_en":"Australia","tel":"61"},
{"name":"奥地利","name_en":"Austria","tel":"43"},
{"name":"澳门(中国)","name_en":"Macao","tel":"853"},
{"name":"安道尔共和国","name_en":"Andorra","tel":"376"},
{"name":"安哥拉","name_en":"Angola","tel":"244"},
{"name":"安圭拉岛","name_en":"Anguilla","tel":"1264"},
{"name":"安提瓜和巴布达","name_en":"AntiguaandBarbuda","tel":"1268"}
]
},
{
"title":"B",
"lists":[
{"name":"巴巴多斯","name_en":"Barbados","tel":"1246"},
{"name":"巴布亚新几内亚","name_en":"PapuaNewCuinea","tel":"971"},
{"name":"巴哈马","name_en":"Bahamas","tel":"1242"},
{"name":"巴基斯坦","name_en":"Pakistan","tel":"92"},
{"name":"巴拉圭","name_en":"Paraguay","tel":"595"},
{"name":"巴勒斯坦","name_en":"Palestine","tel":"970"},
{"name":"巴林","name_en":"Bahrain","tel":"973"},
{"name":"巴拿马","name_en":"Panama","tel":"507"},
{"name":"巴西","name_en":"Brazil","tel":"55"},
{"name":"白俄罗斯","name_en":"Belarus","tel":"375"},
{"name":"百慕大群岛","name_en":"BermudaIs","tel":"1441"},
{"name":"保加利亚","name_en":"Bulgaria","tel":"359"},
{"name":"贝宁","name_en":"Benin","tel":"229"},
{"name":"秘鲁","name_en":"Peru","tel":"51"},
{"name":"比利时","name_en":"Belgium","tel":"32"},
{"name":"冰岛","name_en":"Iceland","tel":"354"},
{"name":"波多黎各","name_en":"PuertoRico","tel":"1787"},
{"name":"波兰","name_en":"Poland","tel":"48"},
{"name":"玻利维亚","name_en":"Bolivia","tel":"591"},
{"name":"伯利兹","name_en":"Belize","tel":"501"},
{"name":"博茨瓦纳","name_en":"Botswana","tel":"267"},
{"name":"布基纳法索","name_en":"Burkina-faso","tel":"226"},
{"name":"布隆迪","name_en":"Burundi","tel":"257"}
]
},
{
"title":"C",
"lists":[
{"name":"朝鲜","name_en":"NorthKorea","tel":"850"}
]
},
{
"title":"D",
"lists":[
{"name":"丹麦","name_en":"Denmark","tel":"45"},
{"name":"德国","name_en":"Germany","tel":"49"},
{"name":"多哥","name_en":"Togo","tel":"228"},
{"name":"多米尼加共和国","name_en":"DominicaRep","tel":"1890"}
]
},
{
"title":"E",
"lists":[
{"name":"厄瓜多尔","name_en":"Ecuador","tel":"593"},
{"name":"俄罗斯","name_en":"Russia","tel":"7"}
]
},
{
"title":"F",
"lists":[
{"name":"法国","name_en":"France","tel":"33"},
{"name":"法属玻利尼西亚","name_en":"FrenchPolynesia","tel":"675"},
{"name":"法属圭亚那","name_en":"FrenchGuiana","tel":"594"},
{"name":"斐济","name_en":"Fiji","tel":"679"},
{"name":"菲律宾","name_en":"Philippines","tel":"63"},
{"name":"芬兰","name_en":"Finland","tel":"358"}
]
},
{
"title":"G",
"lists":[
{"name":"刚果","name_en":"Congo","tel":"242"},
{"name":"冈比亚","name_en":"Gambia","tel":"220"},
{"name":"格林纳达","name_en":"Grenada","tel":"1809"},
{"name":"哥伦比亚","name_en":"Colombia","tel":"57"},
{"name":"格鲁吉亚","name_en":"Georgia","tel":"995"},
{"name":"哥斯达黎加","name_en":"CostaRica","tel":"506"},
{"name":"古巴","name_en":"Cuba","tel":"53"},
{"name":"关岛","name_en":"Guam","tel":"1671"},
{"name":"圭亚那","name_en":"Guyana","tel":"592"}
]
},
{
"title":"H",
"lists":[
{"name":"哈萨克斯坦","name_en":"Kazakstan","tel":"327"},
{"name":"海地","name_en":"Haiti","tel":"509"},
{"name":"韩国","name_en":"Korea","tel":"82"},
{"name":"荷兰","name_en":"Netherlands","tel":"31"},
{"name":"洪都拉斯","name_en":"Honduras","tel":"504"}
]
},
{
"title":"I",
"lists":[
]
},
{
"title":"J",
"lists":[
{"name":"加纳","name_en":"Ghana","tel":"233"},
{"name":"加拿大","name_en":"Canada","tel":"1"},
{"name":"加蓬","name_en":"Gabon","tel":"241"},
{"name":"几内亚","name_en":"Guinea","tel":"224"},
{"name":"捷克","name_en":"Czech","tel":"420"},
{"name":"吉布提","name_en":"Djibouti","tel":"253"},
{"name":"吉尔吉斯坦","name_en":"Kyrgyzstan","tel":"331"},
{"name":"柬埔寨","name_en":"Kampuchea(Cambodia)","tel":"855"},
{"name":"津巴布韦","name_en":"Zimbabwe","tel":"263"}
]
},
{
"title":"K",
"lists":[
{"name":"喀麦隆","name_en":"Cameroon","tel":"237"},
{"name":"卡塔尔","name_en":"Qatar","tel":"974"},
{"name":"科特迪瓦共和国","name_en":"RepublicofIvoryCoast","tel":"225"},
{"name":"科威特","name_en":"Kuwait","tel":"965"},
{"name":"肯尼亚","name_en":"Kenya","tel":"254"},
{"name":"库克群岛","name_en":"CookIs","tel":"682"},
{"name":"拉脱维亚","name_en":"Latvia","tel":"371"},
{"name":"莱索托","name_en":"Lesotho","tel":"266"}
]
},
{
"title":"L",
"lists":[
{"name":"老挝","name_en":"Laos","tel":"856"},
{"name":"黎巴嫩","name_en":"Lebanon","tel":"961"},
{"name":"列支敦士登","name_en":"Liechtenstein","tel":"423"},
{"name":"利比里亚","name_en":"Liberia","tel":"231"},
{"name":"利比亚","name_en":"Libya","tel":"218"},
{"name":"立陶宛","name_en":"Lithuania","tel":"370"},
{"name":"卢森堡","name_en":"Luxembourg","tel":"352"},
{"name":"罗马尼亚","name_en":"Romania","tel":"40"}
]
},
{
"title":"M",
"lists":[
{"name":"马尔代夫","name_en":"Maldives","tel":"960"},
{"name":"马耳他","name_en":"Malta","tel":"356"},
{"name":"美国","name_en":"UnitedStatesofAmerica","tel":"1"},
{"name":"马达加斯加","name_en":"Madagascar","tel":"261"},
{"name":"马拉维","name_en":"Malawi","tel":"265"},
{"name":"马来西亚","name_en":"Malaysia","tel":"60"},
{"name":"马里","name_en":"Mali","tel":"223"},
{"name":"毛里求斯","name_en":"Mauritius","tel":"230"},
{"name":"蒙古","name_en":"Mongolia","tel":"976"},
{"name":"蒙特塞拉特岛","name_en":"MontserratIs","tel":"1664"},
{"name":"缅甸","name_en":"Burma","tel":"95"},
{"name":"摩尔多瓦","name_en":"Moldova,Republicof","tel":"373"},
{"name":"孟加拉国","name_en":"Bangladesh","tel":"880"},
{"name":"摩洛哥","name_en":"Morocco","tel":"212"},
{"name":"摩纳哥","name_en":"Monaco","tel":"377"},
{"name":"墨西哥","name_en":"Mexico","tel":"52"},
{"name":"莫桑比克","name_en":"Mozambique","tel":"258"}
]
},
{
"title":"N",
"lists":[
{"name":"纳米比亚","name_en":"Namibia","tel":"264"},
{"name":"南非","name_en":"SouthAfrica","tel":"27"},
{"name":"南斯拉夫","name_en":"Yugoslavia","tel":"381"},
{"name":"瑙鲁","name_en":"Nauru","tel":"674"},
{"name":"尼加拉瓜","name_en":"Nicaragua","tel":"505"},
{"name":"尼泊尔","name_en":"Nepal","tel":"977"},
{"name":"尼日尔","name_en":"Niger","tel":"977"},
{"name":"尼日利亚","name_en":"Nigeria","tel":"234"},
{"name":"挪威","name_en":"Norway","tel":"47"}
]
},
{
"title":"O",
"lists":[
]
},
{
"title":"P",
"lists":[
{"name":"葡萄牙","name_en":"Portugal","tel":"351"}
]
},
{
"title":"Q",
"lists":[
]
},
{
"title":"R",
"lists":[
{"name":"日本","name_en":"Japan","tel":"81"},
{"name":"瑞典","name_en":"Sweden","tel":"46"},
{"name":"瑞士","name_en":"Switzerland","tel":"41"}
]
},
{
"title":"S",
"lists":[
{"name":"萨尔瓦多","name_en":"EISalvador","tel":"503"},
{"name":"塞浦路斯","name_en":"Cyprus","tel":"53"},
{"name":"塞拉利昂","name_en":"SierraLeone","tel":"232"},
{"name":"塞内加尔","name_en":"Senegal","tel":"221"},
{"name":"塞舌尔","name_en":"Seychelles","tel":"248"},
{"name":"沙特阿拉伯","name_en":"SaudiArabia","tel":"966"},
{"name":"圣多美和普林西比","name_en":"SaoTomeandPrincipe","tel":"239"},
{"name":"圣卢西亚","name_en":"St.Lucia","tel":"1758"},
{"name":"圣马力诺","name_en":"SanMarino","tel":"378"},
{"name":"斯里兰卡","name_en":"SriLanka","tel":"94"},
{"name":"斯洛文尼亚","name_en":"Slovenia","tel":"386"},
{"name":"斯洛伐克","name_en":"Slovakia","tel":"421"},
{"name":"斯威士兰","name_en":"Swaziland","tel":"268"},
{"name":"苏丹","name_en":"Sudan","tel":"249"},
{"name":"苏里南","name_en":"Suriname","tel":"597"},
{"name":"圣文森特岛","name_en":"SaintVincent","tel":"1784"},
{"name":"所罗门群岛","name_en":"SolomonIs","tel":"677"},
{"name":"索马里","name_en":"Somali","tel":"252"}
]
},
{
"title":"T",
"lists":[
{"name":"塔吉克斯坦","name_en":"Tajikstan","tel":"992"},
{"name":"泰国","name_en":"Thailand","tel":"66"},
{"name":"坦桑尼亚","name_en":"Tanzania","tel":"255"},
{"name":"汤加","name_en":"Tonga","tel":"676"},
{"name":"台湾(中国)","name_en":"Taiwan","tel":"886"},
{"name":"特立尼达和多巴哥","name_en":"TrinidadandTobago","tel":"1809"},
{"name":"土库曼斯坦","name_en":"Turkmenistan","tel":"993"},
{"name":"突尼斯","name_en":"Tunisia","tel":"216"},
{"name":"土耳其","name_en":"Turkey","tel":"90"}
]
},
{
"title":"U",
"lists":[
]
},
{
"title":"V",
"lists":[
]
}, {
"title":"W",
"lists":[
{"name":"危地马拉","name_en":"Guatemala","tel":"502"},
{"name":"委内瑞拉","name_en":"Venezuela","tel":"58"},
{"name":"文莱","name_en":"Brunei","tel":"673"},
{"name":"乌干达","name_en":"Uganda","tel":"256"},
{"name":"乌克兰","name_en":"Ukraine","tel":"380"},
{"name":"乌拉圭","name_en":"Uruguay","tel":"598"},
{"name":"乌兹别克斯坦","name_en":"Uzbekistan","tel":"233"}
]
},
{
"title":"X",
"lists":[
{"name":"西班牙","name_en":"Spain","tel":"34"},
{"name":"希腊","name_en":"Greece","tel":"30"},
{"name":"香港(中国)","name_en":"Hongkong","tel":"852"},
{"name":"新加坡","name_en":"Singapore","tel":"65"},
{"name":"新西兰","name_en":"NewZealand","tel":"64"},
{"name":"匈牙利","name_en":"Hungary","tel":"36"},
{"name":"叙利亚","name_en":"Syria","tel":"963"}
]
}, {
"title":"Y",
"lists":[
{"name":"牙买加","name_en":"Jamaica","tel":"1876"},
{"name":"也门","name_en":"Yemen","tel":"967"},
{"name":"意大利","name_en":"Italy","tel":"39"},
{"name":"伊拉克","name_en":"Iraq","tel":"964"},
{"name":"伊朗","name_en":"Iran","tel":"98"},
{"name":"以色列","name_en":"Israel","tel":"972"},
{"name":"印度","name_en":"India","tel":"97"},
{"name":"印度尼西亚","name_en":"Indonesia","tel":"62"},
{"name":"英国","name_en":"UnitedKiongdom","tel":"44"},
{"name":"约旦","name_en":"Jordan","tel":"962"},
{"name":"越南","name_en":"Vietnam","tel":"84"}
]
},
{
"title":"Z",
"lists":[
{"name":"赞比亚","name_en":"Zambia","tel":"260"},
{"name":"乍得","name_en":"Chad","tel":"235"},
{"name":"扎伊尔","name_en":"Zaire","tel":"243"},
{"name":"直布罗陀","name_en":"Gibraltar","tel":"350"},
{"name":"智利","name_en":"Chile","tel":"56"},
{"name":"中非共和国","name_en":"CentralAfricanRepublic","tel":"236"},
{"name":"中国","name_en":"China","tel":"86"}
]
}
]
}

View File

@ -0,0 +1,52 @@
<?php
/**
* 分库分表的自定义数据库路由配置
*
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author: dogstar <chanzonghuang@gmail.com> 2015-02-09
*/
return array(
/**
* DB数据库服务器集群
*/
'servers' => array(
'db_master' => array( //服务器标记
'type' => 'mysql', //数据库类型暂时只支持mysql, sqlserver
'host' => '127.0.0.1', //数据库域名
'name' => '', //数据库名字
'user' => '', //数据库用户名
'password' => '', //数据库密码
'port' => 3306, //数据库端口
'charset' => 'utf8mb4', //数据库字符集
),
),
/**
* 自定义路由表
*/
'tables' => array(
// 通用路由
'__default__' => array( // 固定的系统标志,不能修改!
'prefix' => 'cmf_', // 数据库统一表名前缀,无前缀保留空
'key' => 'id', // 数据库统一表主键名通常为id
'map' => array( // 数据库统一默认存储路由
array('db' => 'db_master'), // db_master对应前面servers.db_master配置须对应
),
),
// 单表路由(当某个表的配置或存储或存在分表时,可单独配置,请参考以下示例)
/**
'demo' => array( // 表名,不带表前缀,不带分表后缀
'prefix' => '', // 当前的表名前缀
'key' => 'id', // 当前的表主键名
'map' => array( // 当前的分表存储路由配置
array('db' => 'db_master'), // 单表配置array('db' => 服务器标记)
array('start' => 0, 'end' => 2, 'db' => 'db_master'), // 三张分表的配置array('start' => 开始下标, 'end' => 结束下标, 'db' => 服务器标记)
),
),
*/
),
);

65
web/PhalApi/config/di.php Normal file
View File

@ -0,0 +1,65 @@
<?php
/**
* DI依赖注入配置文件
*
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2017-07-13
*/
use PhalApi\Loader;
use PhalApi\Config\FileConfig;
use PhalApi\Logger;
use PhalApi\Logger\FileLogger;
use PhalApi\Database\NotORMDatabase;
/** ---------------- 基本注册 必要服务组件 ---------------- **/
$di = \PhalApi\DI();
// 配置
$di->config = new FileConfig(API_ROOT . '/config');
// 调试模式,$_GET['__debug__']可自行改名
//$di->debug = !empty($_GET['__debug__']) ? true : $di->config->get('sys.debug');
$di->debug = false;
// 日记纪录
$di->logger = new FileLogger(API_ROOT . '/runtime', Logger::LOG_LEVEL_DEBUG | Logger::LOG_LEVEL_INFO | Logger::LOG_LEVEL_ERROR);
// 数据操作 - 基于NotORM
$di->notorm = new NotORMDatabase($di->config->get('dbs'), $di->config->get('sys.notorm_debug'));
\App\connectionRedis();
// JSON中文输出
// $di->response = new \PhalApi\Response\JsonResponse(JSON_UNESCAPED_UNICODE);
/** ---------------- 定制注册 可选服务组件 ---------------- **/
// 签名验证服务
// $di->filter = new \PhalApi\Filter\SimpleMD5Filter();
// 缓存 - Memcache/Memcached
// $di->cache = function () {
// return new \PhalApi\Cache\MemcacheCache(\PhalApi\DI()->config->get('sys.mc'));
// };
// 支持JsonP的返回
// if (!empty($_GET['callback'])) {
// $di->response = new \PhalApi\Response\JsonpResponse($_GET['callback']);
// }
// 生成二维码扩展,参考示例:?s=App.Examples_QrCode.Png
// $di->qrcode = function() {
// return new \PhalApi\QrCode\Lite();
// };
// 注册扩展的追踪器将SQL写入日志文件
// $di->tracer = function() {
// return new \App\Common\Tracer();
// };
$di->qiniu = function() {
return new \PhalApi\Qiniu\Lite();
};

View File

@ -0,0 +1,37 @@
<?php
/**
* 以下配置为系统级的配置,通常放置不同环境下的不同配置
*
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2017-07-13
*/
return array(
/**
* @var boolean 是否开启接口调试模式,开启后在客户端可以直接看到更多调试信息
*/
'debug' => false,
/**
* @var boolean 是否开启NotORM调试模式开启后仅针对NotORM服务开启调试模式
*/
'notorm_debug' => false,
/**
* @var boolean 是否纪录SQL到日志需要同时开启notorm_debug方可写入日志
*/
'enable_sql_log' => false,
/**
* @var boolean 是否开启URI匹配若未提供service或s参数且开启enable_uri_match才尝试进行URI路由匹配。例如/App/User/Login映射到s=App.Usre.Login
*/
'enable_uri_match' => false,
/**
* 加密
*/
'crypt' => array(
'mcrypt_iv' => '12345678', //8位
),
);

View File

@ -0,0 +1,9 @@
<?php
// 德语 de - de 德标
// 德语 de - at 奥地利
// 德语 de - ch 瑞士
// 德语 de - ru 俄罗斯(欧境)
return array(
'Hi {name}, welcome to use PhalApi!' => '{name}Hallo, Willkommen PhalApi',
'user not exists' => 'Der nutzer gibt es nicht',
);

View File

@ -0,0 +1,179 @@
<?php
//\PhalApi\T
//例: '你好,{n}'=>'hello,{n}'
return array(
'您的登陆状态失效,请重新登陆!'=>'Your logging status is invalid, please login again!',
'信息错误'=>'Information error',
'签名错误'=>'Signature error',
'该账号已被禁用'=>'This account has been disabled',
'余额不足'=>'Insufficient balance',
'操作成功'=>'Operation succeeded',
'发送失败'=>'Delivery failed',
'半小时'=>'Half an hour',
'小时'=>'Hours',
'局'=>'Ju',
'张'=>'Zhang',
'次'=>'Ci',
'幅'=>'Fu',
'部'=>'Bu',
'首'=>'Shou',
/* functions */
'验证码'=>'Verification code',
'您的验证码是:{$code}。请不要把验证码泄露给其他人'=>'Your verification code is: {$code}. Please dont disclose the verification code to others',
'用户不存在'=>'The user does not exist',
'摩羯座'=>'Capricorn',
'水瓶座'=>'Aquarius',
'双鱼座'=>'Pisces',
'白羊座'=>'Aries',
'金牛座'=>'Taurus',
'双子座'=>'Gemini',
'巨蟹座'=>'Cancer',
'狮子座'=>'Leo',
'处女座'=>'Virgo',
'天秤座'=>'Libra',
'天蝎座'=>'Scorpio',
'射手座'=>'Sagittarius',
'1分钟前'=>'1 minute ago',
'{n}分钟前'=>'{n} minutes ago',
'{n}小时前'=>'{n} hours ago',
'{n}天前'=>'{n} days ago',
'今天'=>'Today',
'明天'=>'Tomorrow',
'后天'=>'The day after tomorrow',
'昨天'=>'Yesterday',
'前天'=>'The day before yesterday',
'邮箱格式错误'=>'Mailbox format error',
/* Cash */
'提现成功'=>'Successful withdrawal',
'请选择提现账号'=>'Please select withdrawal account',
'请输入有效的提现金额'=>'Please type in a valid withdrawal amount',
'不在提现期限内,不能提现'=>'Not within withdrawal period, and withdrawal is not allowed',
'提现最低额度为{n}元'=>'The minimum withdrawal amount is {n} yuan',
'每月只可提现{n}次,已达上限'=>'Only {n} times of withdrawals can be made every month, and the limit has been reached',
'提现账号信息不正确'=>'Incorrect withdrawal account information',
'提现失败,请重试'=>'Withdrawal failed, please try again',
'添加成功'=>'Added successfully',
'银行名称不能为空'=>'It cannot be empty for the bank name',
'账号不能为空'=>'It cannot be empty for the account number',
'添加失败,请重试'=>'Fail to add, please try again',
'删除成功'=>'Deleted successfully',
'删除失败,请重试'=>'Fail to delete, please try again',
/* Charge */
'Google Pay'=>'Google Pay',
'苹果支付'=>'Apple Pay',
'余额支付'=>'Balance payment',
'订单生成失败'=>'Order generation failed',
/* Comment */
'评价成功'=>'Comment completed',
'您已经评价过了'=>'You have already commented',
'订单无效,无法评价'=>'You are unable to comment for the order is invalid',
'最多选择三个标签'=>'Select up to three tags',
'评价失败,请重试'=>'Comment failed, please try again',
/* Home */
'请输入关键词'=>'Please type in keyword',
/* login */
'请输入邮箱'=>'Please type in mailbox',
'请输入密码'=>'Please type in password',
'账号或密码错误'=>'Incorrect account number or password',
'请输入验证码'=>'Please type in verification code',
'请输入确认密码'=>'Please type in confirmation password',
'请先获取验证码'=>'Please get the verification code first',
'验证码已过期,请重新获取'=>'Verification code has expired, please get one again',
'邮箱错误'=>'Mailbox error',
'验证码错误'=>'Verification code error',
'两次密码不一致'=>'Two passwords do not match',
'密码为6-20位数字和字母组合'=>'The password is a combination of 6-20 digits and letters',
'注册成功'=>'Successful Registration',
'陪玩用户'=>'Users playing with others',
'发送成功,请注意查收'=>'Send successfully, please check',
'请输入正确的邮箱'=>'Please type in the correct mailbox',
'该账号已注册'=>'This account is already registered',
'验证码5分钟有效请勿多次发送'=>'Verification code is valid for 5 minutes, please do not send for many times',
'验证码为:{n}'=>'Verification code is: {n}',
'该账号未注册'=>'This account is not registered',
/* Orders */
'已移除'=>'Removed',
'不能给自己下单'=>'You cannot place orders for yourself',
'请选择正确的时间'=>'Please select the correct time',
'备注不能超过50字'=>'Remarks cannot exceed 50 words',
'该技能对方未认证或未开启'=>'The skill is not authenticated or opened by the other side',
'{n}给你下了订单'=>'{n} placed an order for you',
'订单已收到,会尽快确认'=>'The order has been received and will be confirmed as soon as possible',
'订单信息有误'=>'Error in order information',
'该订单不能取消'=>'This order cannot be canceled',
'请选择原因'=>'Please select reasons',
'订单:您取消了一个订单'=>'Order: you canceled an order',
'订单:您取消了一个订单,费用{n}已退回'=>'Order: you canceled an order and the fee {n} has been returned',
'订单:很抱歉,用户取消了您的订单哦~'=>'Order: sorry, the user canceled your order~',
'该订单未付款,无法接单'=>'This order has not been paid and cannot be accepted',
'大神通过了您的订单,快去让大神带起飞吧'=>'The master passed your order, go and let the master carry you',
'订单已处理,无法操作'=>'Order processed, unable to operate',
'订单:很抱歉,大神没通过订单哦'=>"Order: I'm sorry, the master didn't pass the order",
'订单:很抱歉,大神没通过订单哦,费用{n}已退回'=>"Order: I'm sorry, great god didn't pass the order. the fee {n} has been returned",
'对方还未接单,无法完成'=>'The order has not been received yet by the other side, and the it cannot be completed',
'接单:订单已经结束了,收入{n},您可以给用户评价哦'=>'Receipt: the order has been completed and the income is {n}. You can give make a comment on the user',
/* Skill */
'请等待技能认证通过'=>'Please wait for the pass of the skill certification',
'请先设置价格'=>'Please set the price first',
'请选择正确的价格'=>'Please select the correct price',
'介绍最多30个字'=>'Introduction up to 30 words',
'技能不存在'=>'Skill does not exist',
'对方未认证此技能'=>'The other party has not authenticated this skill',
/* User */
'订单中心'=>'Order center',
'我的钱包'=>'My wallet',
'我的技能'=>'My skills',
'申请大神'=>'Apply for being the master',
'实名认证'=>'Real name authentication',
'设置'=>'Settings',
'请上传头像'=>'Please upload head portrait',
'请设置您的昵称'=>'Please set your nickname',
'请选择出生日期'=>'Please select the date of birth',
'请选择您的性别'=>'Please select your gender',
'昵称最多10个字'=>'Nickname can be up to 10 words',
'昵称已存在'=>'Nickname already exists',
'最多选择五个兴趣'=>'Select up to five interests',
'不能关注自己'=>'You cannot follow yourself',
'取消成功'=>'Cancellation Successful',
'关注成功'=>'Focus on success',
'来自{n}'=>'From {n}',
'女生'=>'Girls',
'男生'=>'Boys',
'{n}后'=>'After {n}',
'喜欢{n}'=>'Like {n}',
'从事{n}'=>'Engaged in {n}',
'毕业于{n}'=>'Graduated from {n}',
);

View File

@ -0,0 +1,7 @@
<?php
// 法语 fr - fr 法标
// 法语 fr - lu 卢森堡
return array(
'Hi {name}, welcome to use PhalApi!' => '{name}Bonjour, bienvenue PhalApi',
'user not exists' => "L'utilisateur n'existe pas",
);

View File

@ -0,0 +1,14 @@
<?php
/**
* 翻译说明:
*
* 1、带大括号的保留原来写法,如:{name},会被系统动态替换
* 2、没在以下出现的,可以自行追加
*
* @author dogstar <chanzonghuang@gmail.com> 2015-02-09
*/
return array(
'Hi {name}, welcome to use PhalApi!' => '{name}您好欢迎使用PhalApi',
'user not exists' => '用户不存在',
);

View File

@ -0,0 +1,6 @@
<?php
return array(
'Hi {name}, welcome to use PhalApi!' => '{name}您好歡迎使用PhalApi',
'user not exists' => '用戶不存在',
);

View File

@ -0,0 +1,47 @@
<?php
/**
* PhalApi在线接口列表文档 - 自动生成
*
* - 对Api_系列的接口进行罗列
* - 按service进行字典排序
* - 支持多级目录扫描
*
* <br>使用示例:<br>
* ```
* <?php
* // 左侧菜单说明
* class Demo extends Api {
* /**
* * 接口服务名称
* * @desc 更多说明
* * /
* public function index() {
* }
* }
* ```
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author xiaoxunzhao 2015-10-25
* @modify Aevit 2014-10-29
* @modify shwy 2017-03-02
* @modify dogstar 2017-06-17
*/
require_once dirname(__FILE__) . '/init.php';
$projectName = 'PhalApi开源接口框架';
if (substr(PHP_SAPI, 0, 3) == 'cli') {
// 生成离线文档
$apiHtml = new \PhalApi\Helper\ApiStaticCreate($projectName);
$apiHtml->render();
} else if (!empty($_GET['detail'])) {
// 接口详情页
$apiDesc = new \PhalApi\Helper\ApiDesc($projectName);
$apiDesc->render(API_ROOT . '/src/view/docs/api_desc_tpl.php');
} else {
// 接口列表页
$apiList = new \PhalApi\Helper\ApiList($projectName);
$apiList->render(API_ROOT . '/src/view/docs/api_list_tpl.php');
}

View File

@ -0,0 +1,10 @@
<?php
/**
* 统一访问入口
*/
require_once dirname(__FILE__) . '/init.php';
$pai = new \PhalApi\PhalApi();
$pai->response()->output();

View File

@ -0,0 +1,28 @@
<?php
/**
* 统一初始化
*/
// 定义项目路径
defined('API_ROOT') || define('API_ROOT', dirname(__FILE__) . '/..');
// 引入composer
require_once API_ROOT . '/vendor/autoload.php';
// 时区设置
date_default_timezone_set('Asia/Shanghai');
// 引入DI服务
include API_ROOT . '/config/di.php';
// 调试模式
if (\PhalApi\DI()->debug) {
// 启动追踪器
\PhalApi\DI()->tracer->mark('PHALAPI_INIT');
error_reporting(E_ALL);
ini_set('display_errors', 'On');
}
// 翻译语言包设定
\PhalApi\SL('zh_cn');

BIN
web/PhalApi/src/.DS_Store vendored Normal file

Binary file not shown.

BIN
web/PhalApi/src/app/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,261 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\Cash as Domain_Cash;
/**
* 提现
*/
class Cash extends Api {
public function getRules() {
return array(
'setCash' => array(
'accountid' => array('name' => 'accountid', 'type' => 'int', 'desc' => '账号ID'),
'cashvote' => array('name' => 'cashvote', 'type' => 'int', 'desc' => '提现的票数'),
),
'setCashgift' => array(
'accountid' => array('name' => 'accountid', 'type' => 'int', 'desc' => '账号ID'),
'cashvote' => array('name' => 'cashvote', 'type' => 'int', 'desc' => '提现的票数'),
'cashmoney' => array('name' => 'cashmoney', 'type' => 'float', 'desc' => '提现金额'),
),
'setUserAccount' => array(
'type' => array('name' => 'type', 'type' => 'int', 'desc' => '账号类型1表示支付宝2表示微信3表示银行卡'),
'account_bank' => array('name' => 'account_bank', 'type' => 'string', 'default' => '', 'desc' => '银行名称'),
'account' => array('name' => 'account', 'type' => 'string', 'desc' => '账号'),
'name' => array('name' => 'name', 'type' => 'string', 'default' => '', 'desc' => '姓名'),
),
'delUserAccount' => array(
'id' => array('name' => 'id', 'type' => 'int', 'desc' => '账号ID'),
),
);
}
/**
* 我的收益:订单收益
* @desc 用于获取用户收益,包括可体现金额,今日可提现金额
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].votes 可提取映票数
* @return string info[0].votestotal 总映票
* @return string info[0].cash_rate 映票兑换比例
* @return string info[0].total 可体现金额
* @return string info[0].tips 温馨提示
* @return string msg 提示信息
*/
public function getProfit() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Cash();
$info = $domain->getProfit($uid);
$rs['info'][0]=$info;
return $rs;
}
/**
* 用户提现:订单收益提现
* @desc 用于进行用户提现
* @return int code 操作码0表示成功
* @return array info
* @return string msg 提示信息
*/
public function setCash() {
$rs = array('code' => 0, 'msg' => \PhalApi\T('提现成功'), 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$accountid=\App\checkNull($this->accountid);
$cashvote=\App\checkNull($this->cashvote);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
if(!$accountid){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('请选择提现账号');
return $rs;
}
if($cashvote<=0){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('请输入有效的提现金额');
return $rs;
}
$data=array(
'uid'=>$uid,
'accountid'=>$accountid,
'cashvote'=>$cashvote,
);
$domain = new Domain_Cash();
$info = $domain->setCash($data);
return $info;
}
/**
* 获取用户提现账号
* @desc 用于获取用户提现账号
* @return int code 操作码0表示成功
* @return array info
* @return string info[].id 账号ID
* @return string info[].type 账号类型
* @return string info[].account_bank 银行名称
* @return string info[].account 账号
* @return string info[].name 姓名
* @return string msg 提示信息
*/
public function getUserAccountList() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Cash();
$info = $domain->getUserAccountList($uid);
$rs['info']=$info;
return $rs;
}
/**
* 设置用户提现账号
* @desc 用于设置用户提现账号
* @return int code 操作码0表示成功
* @return array info
* @return string msg 提示信息
*/
public function setUserAccount() {
$rs = array('code' => 0, 'msg' => \PhalApi\T('添加成功'), 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$type=\App\checkNull($this->type);
$account_bank=\App\checkNull($this->account_bank);
$account=\App\checkNull($this->account);
$name=\App\checkNull($this->name);
if($type==3){
if($account_bank==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('银行名称不能为空');
return $rs;
}
}
if($account==''){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('账号不能为空');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$data=array(
'uid'=>$uid,
'type'=>$type,
'account_bank'=>$account_bank,
'account'=>$account,
'name'=>$name,
'addtime'=>time(),
);
$domain = new Domain_Cash();
$result = $domain->setUserAccount($data);
if(!$result){
$rs['code'] = 1003;
$rs['msg'] = \PhalApi\T('添加失败,请重试');
return $rs;
}
$rs['info'][0]=$result;
return $rs;
}
/**
* 删除用户提现账号
* @desc 用于删除用户提现账号
* @return int code 操作码0表示成功
* @return array info
* @return string msg 提示信息
*/
public function delUserAccount() {
$rs = array('code' => 0, 'msg' => '删除成功', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$id=\App\checkNull($this->id);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$data=array(
'uid'=>$uid,
'id'=>$id,
);
$domain = new Domain_Cash();
$result = $domain->delUserAccount($data);
if(!$result){
$rs['code'] = 1003;
$rs['msg'] = \PhalApi\T('删除失败,请重试');
return $rs;
}
return $rs;
}
}

View File

@ -0,0 +1,292 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\Charge as Domain_Charge;
/**
* 充值
*/
class Charge extends Api {
public function getRules() {
return array(
'getBalance' => array(
'type' => array('name' => 'type', 'type' => 'int','desc' => 'APP类型1是安卓2是IOS'),
'version' => array('name' => 'version', 'type' => 'string','desc' => '版本号'),
),
'getOrder' => array(
'changeid' => array('name' => 'changeid', 'type' => 'string', 'desc' => '充值规则ID'),
'coin' => array('name' => 'coin', 'type' => 'string', 'desc' => '钻石'),
'money' => array('name' => 'money', 'type' => 'string', 'desc' => '充值金额'),
'type' => array('name' => 'type', 'type' => 'int', 'desc' => '充值方式ID'),
),
);
}
/**
* 充值规则
* @desc 用于获取充值规则
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string info[].id 规则ID
* @return string info[].money 金额
* @return string info[].coin 非苹果支付钻石数
* @return string info[].coin_ios 苹果支付钻石数
* @return string info[].product_id 规则ID
* @return string info[].give 赠送
* @return string msg 提示信息
*/
public function getChargeRules() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$domain = new Domain_Charge();
$info = $domain->getChargeRules();
$rs['info'] =$info;
return $rs;
}
/**
* 我的钻石
* @desc 用于获取用户余额,充值规则 支付方式信息
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].coin 用户余额
* @return array info[0].rules 充值规则
* @return string info[0].rules[].id 规则ID
* @return string info[0].rules[].money 金额
* @return string info[0].rules[].coin 非苹果支付钻石数
* @return string info[0].rules[].coin_ios 苹果支付钻石数
* @return string info[0].rules[].product_id 苹果项目ID
* @return string info[0].rules[].give 赠送钻石为0时不显示赠送
* @return array info[0].paylist 支付方式列表
* @return string info[0].paylist[].id apple苹果
* @return string info[0].paylist[].name 名称
* @return string info[0].paylist[].thumb 图标
* @return object info[0].ali 支付宝信息
* @return string info[0].ali.partner 合作者ID
* @return string info[0].ali.seller_id 账号
* @return string info[0].ali.key PKCS8密钥
* @return string msg 提示信息
*/
public function getBalance() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$type=\App\checkNull($this->type);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Charge();
$info = \App\getUserCoin($uid);
$rules= $domain->getChargeRules();
$info['rules'] =$rules;
$configpri=\App\getConfigPri();
$aliapp_switch=$configpri['aliapp_switch'];
$paylist=[];
if($aliapp_switch==1){
$paylist[]=[
'id'=>'1',
'name'=>\PhalApi\T('支付宝支付'),
'thumb'=>\App\get_upload_path("/static/app/pay/ali.png"),
];
}
$info['paylist'] =$paylist;
$ali=[
'partner'=>$configpri['aliapp_partner'],
'seller_id'=>$configpri['aliapp_seller_id'],
'key'=>$configpri['aliapp_key'],
];
$info['ali'] =$ali;
$rs['info'][0]=$info;
return $rs;
}
/**
* 获取订单信息
* @desc 用于支付前获取订单信息
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].orderid 订单号
* @return object info[0].ali 支付宝信息
* @return string info[0].ali.partner 合作者ID
* @return string info[0].ali.seller_id 账号
* @return string info[0].ali.key PKCS8密钥
* @return object info[0].wx 微信信息
* @return string info[0].wx.appid 微信Appid
* @return string info[0].wx.noncestr 随机数
* @return string info[0].wx.package 固定数据
* @return string info[0].wx.partnerid 商户ID
* @return string info[0].wx.prepayid 支付ID
* @return string info[0].wx.timestamp 时间戳
* @return string msg 提示信息
*/
public function getOrder() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$changeid=\App\checkNull($this->changeid);
$coin=\App\checkNull($this->coin);
$money=\App\checkNull($this->money);
$type=\App\checkNull($this->type);
if($uid<1 || $changeid<1 || $coin<=0 || $money<=0 || $type<1){
$rs['code']=1002;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$configpri = \App\getConfigPri();
$orderid=$uid.'_'.date('ymdHis').rand(100,999)."_"."1";//1充值2订单
$domain = new Domain_Charge();
$info = $domain->setOrder($changeid,$orderinfo);
if(!$info){
$rs['code']=1001;
$rs['msg']=\PhalApi\T('订单生成失败');
return $rs;
}else if($info['code']!=0){
return $info;
}
$ali=[
'partner'=>'',
'seller_id'=>'',
'key'=>'',
];
if($type==1){
/* 支付宝 */
if($configpri['aliapp_partner']=='' || $configpri['aliapp_seller_id']=='' || $configpri['aliapp_key']==''){
$rs['code']=1011;
$rs['msg']=\PhalApi\T('支付宝未配置');
return $rs;
}
$ali=[
'partner'=>$configpri['aliapp_partner'],
'seller_id'=>$configpri['aliapp_seller_id'],
'key'=>$configpri['aliapp_key'],
];
}
$rs['info'][0]['orderid']=$orderid;
$rs['info'][0]['ali']=$ali;
return $rs;
}
/**
* sign拼装获取
*/
protected function sign($param,$key){
$sign = "";
foreach($param as $k => $v){
$sign .= $k."=".$v."&";
}
$sign .= "key=".$key;
$sign = strtoupper(md5($sign));
return $sign;
}
protected function getTestOrder() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$changeid=\App\checkNull($this->changeid);
$coin=\App\checkNull($this->coin);
$money=\App\checkNull($this->money);
if($uid<1 || $changeid<1 || $coin<=0 || $money<=0){
$rs['code']=1002;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$type=4;
$orderid=$this->getOrderid($uid);
$orderinfo=array(
"uid"=>$uid,
"touid"=>$uid,
"money"=>$money,
"coin"=>$coin,
"orderno"=>$orderid,
"type"=>$type,
"status"=>1,
"addtime"=>time(),
"ambient"=>0
);
$domain = new Domain_Charge();
$info = $domain->setOrder($changeid,$orderinfo);
if(!$info){
$rs['code']=1001;
$rs['msg']=\PhalApi\T('订单生成失败');
return $rs;
}else if($info['code']!=0){
return $info;
}
\PhalApi\DI()->notorm->user
->where('id = ? ', $uid)
->update(array('coin' => new \NotORM_Literal("coin + {$coin}")) );
$rs['info'][0]['orderid']=$orderid;
return $rs;
}
}

View File

@ -0,0 +1,196 @@
<?php
namespace App\Api;
use PhalApi\Api;
use App\Domain\Comment as Domain_Comment;
/**
* 评论
*/
class Comment extends Api {
public function getRules() {
return array(
'setComment' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单id'),
'content' => array('name' => 'content', 'type' => 'string', 'desc' => '内容'),
'star' => array('name' => 'star', 'type' => 'int', 'desc' => '星级'),
'label' => array('name' => 'label', 'type' => 'string', 'default'=>'', 'desc' => '标签ID多个用,拼接'),
'sign' => array('name' => 'sign', 'type' => 'string', 'desc' => '签名'),
),
'setEvaluate' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单id'),
'content' => array('name' => 'content', 'type' => 'string', 'desc' => '内容'),
'star' => array('name' => 'star', 'type' => 'int', 'desc' => '星级'),
'sign' => array('name' => 'sign', 'type' => 'string', 'desc' => '签名'),
),
'getComment' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'desc' => '主播ID'),
'p' => array('name' => 'p', 'type' => 'int', 'default'=>'1', 'desc' => '页码'),
),
);
}
/**
* 评论
* @desc 用于用户评论主播
* @return int code 操作码0表示成功
* @return array info 列表
* @return string msg 提示信息
*/
public function setComment() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid = \App\checkNull($this->uid);
$token = \App\checkNull($this->token);
$orderid = \App\checkNull($this->orderid);
$content = \App\checkNull($this->content);
$star = \App\checkNull($this->star);
$label = \App\checkNull($this->label);
$sign = \App\checkNull($this->sign);
if($uid<1 || $token=='' || $orderid<1 || $star<1 || $star > 5 || $sign==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkdata=array(
'uid'=>$uid,
'token'=>$token,
'orderid'=>$orderid,
'star'=>$star,
);
$issign=\App\checkSign($checkdata,$sign);
if(!$issign){
$rs['code']=1001;
$rs['msg']=\PhalApi\T('签名错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$data=[
'uid'=>$uid,
'orderid'=>$orderid,
'content'=>$content,
'star'=>$star,
'label'=>$label,
];
$domain = new Domain_Comment();
$info = $domain->setComment($data);
return $info;
}
/**
* 评价
* @desc 用于主播评价用户
* @return int code 操作码0表示成功
* @return array info 列表
* @return string msg 提示信息
*/
public function setEvaluate() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid = \App\checkNull($this->uid);
$token = \App\checkNull($this->token);
$orderid = \App\checkNull($this->orderid);
$content = \App\checkNull($this->content);
$star = \App\checkNull($this->star);
$sign = \App\checkNull($this->sign);
if($uid<1 || $token=='' || $orderid<1 || $star<1 || $star > 5 || $sign==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkdata=array(
'uid'=>$uid,
'token'=>$token,
'orderid'=>$orderid,
'star'=>$star,
);
$issign=\App\checkSign($checkdata,$sign);
if(!$issign){
$rs['code']=1001;
$rs['msg']=\PhalApi\T('签名错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$data=[
'uid'=>$uid,
'orderid'=>$orderid,
'content'=>$content,
'star'=>$star,
];
$domain = new Domain_Comment();
$info = $domain->setEvaluate($data);
return $info;
}
/**
* 技能评论
* @desc 用于获取技能评论
* @return int code 操作码0表示成功
* @return array info 列表
* @return string info[].id 分类ID
* @return string info[].content 内容
* @return string info[].star 星级
* @return string info[].add_time 时间
* @return object info[].userinfo 用户信息
* @return array info[].label_a 评论标签
* @return string info[].label_a[] 标签
* @return string msg 提示信息
*/
public function getComment() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$skillid = \App\checkNull($this->skillid);
$liveuid = \App\checkNull($this->liveuid);
$p = \App\checkNull($this->p);
if($skillid<1 || $liveuid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$where=[];
$where['liveuid']=$liveuid;
$where['skillid']=$skillid;
$domain = new Domain_Comment();
$list = $domain->getComment($p,$where);
$rs['info']=$list;
return $rs;
}
}

View File

@ -0,0 +1,54 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\Guide as Domain_Guide;
/**
* 引导页
*/
class Guide extends Api {
public function getRules() {
return array(
);
}
/**
* 引导页
* @desc 用于 获取引导页信息
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].switch 开关0关1开
* @return string info[0].type 类型0图片1视频
* @return string info[0].time 图片时间
* @return array info[0].list
* @return string info[0].list[].thumb 图片、视频链接
* @return string info[0].list[].href 页面链接
* @return string msg 提示信息
*/
public function getGuide() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$domain = new Domain_Guide();
$info = $domain->getGuide();
$rs['info'][0]=$info;
return $rs;
}
}

View File

@ -0,0 +1,324 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\Guide as Domain_Guide;
use App\Domain\Home as Domain_Home;
use App\Domain\Skill as Domain_Skill;
use App\Domain\Dynamic as Domain_Dynamic;
/**
* 首页
*/
class Home extends Api {
public function getRules() {
return array(
'getUsers' => array(
'p' => array('name' => 'p', 'type' => 'int','default'=>'1', 'desc' => '页码'),
),
'search' => array(
'keyword' => array('name' => 'keyword', 'type' => 'string', 'desc' => '搜索内容'),
),
'searchMore' => array(
'keyword' => array('name' => 'keyword', 'type' => 'string', 'desc' => '搜索内容'),
'p' => array('name' => 'p', 'type' => 'int','default'=>'1', 'desc' => '页码'),
),
);
}
/**
* 网站信息
* @desc 用于获取网站基本信息
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].site_name 网站名称
* @return string info[0].name_coin 消费币名称
* @return string info[0].apk_ver APK版本号
* @return string info[0].apk_des APK更新说明
* @return string info[0].apk_url APK下载链接
* @return string info[0].ipa_ver IPA版本号
* @return string info[0].ios_shelves IPA上架版本号
* @return string info[0].ipa_des IPA更新说明
* @return string info[0].ipa_url IPA下载链接
* @return array info[0].login_type 登录方式
* @return array info[0].share_type 分享方式
* @return array info[0].admin 私信管理员账号
* @return array info[0].im_admin_drip 抢单大厅的IM管理员
* @return array info[0].admin_dispatch 派单的IM管理员
* @return string msg 提示信息
*/
public function getConfig() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$info=\App\getConfigPub();
unset($info['site_url']);
unset($info['site_seo_title']);
unset($info['site_seo_keywords']);
unset($info['site_seo_description']);
unset($info['copyright']);
unset($info['qr_url']);
$info_pri=\App\getConfigPri();
$login_type=$info_pri['login_type'];
foreach ($login_type as $k => $v) {
if($v=='ios'){
unset($login_type[$k]);
break;
}
}
$login_type=array_values($login_type);
$info['login_type']=$login_type;
$info['share_type']=$info_pri['share_type'];
$info['admin']=$info_pri['im_admin'];
$info['admin_dispatch']=$info_pri['im_admin_dispatch'];
$info['admin_upservice']=$info_pri['im_admin_upservice'];
/* 引导页 */
$domain = new Domain_Guide();
$guide_info = $domain->getGuide();
$info['guide']=$guide_info;
$level= \App\getLevelUserList();
foreach($level as $k=>$v){
unset($v['level_up']);
unset($v['addtime']);
unset($v['id']);
unset($v['levelname']);
$level[$k]=$v;
}
//陪玩等级
$levelanchor= \App\getLevelAnchorList();
foreach($levelanchor as $k=>$v){
unset($v['level_up']);
unset($v['addtime']);
unset($v['id']);
unset($v['levelname']);
$levelanchor[$k]=$v;
}
$info['level']=$level;
$info['levelanchor']=$levelanchor;
$rs['info'][0] = $info;
return $rs;
}
/**
* 首页
* @desc 用于获取首页信息
* @return int code 操作码0表示成功
* @return array info
* @return array info[0].skilllist 技能列表
* @return string info[0].skilllist[].id
* @return string info[0].skilllist[].name 技能名
* @return string info[0].skilllist[].thumb 图标
* @return array info[0].silidelist 轮播
* @return string info[0].silidelist[].image 图片
* @return string info[0].silidelist[].url 链接
* @return array info[0].dynamic_list 动态列表
* @return string info[0].dynamic_list[].user_nickname 昵称
* @return string info[0].dynamic_list[].avatar 头像
* @return string info[0].dynamic_list[].sex 性别
* @return string info[0].dynamic_list[].age 年龄
* @return string info[0].dynamic_list[].addr 地址
* @return string info[0].dynamic_list[].isattent 是否关注,0否1是
* @return string info[0].dynamic_list[].islike 是否点赞,0否1是
* @return string info[0].dynamic_list[].type 动态类型0纯文字1图片2视频3语音
* @return string info[0].dynamic_list[].content 文字内容
* @return array info[0].dynamic_list[].thumbs 图片集
* @return string info[0].dynamic_list[].thumbs[] 图片链接
* @return string info[0].dynamic_list[].video 视频链接
* @return string info[0].dynamic_list[].video_t 视频封面
* @return string info[0].dynamic_list[].voice 语音链接
* @return string info[0].dynamic_list[].voice_l 语音时长
* @return string info[0].dynamic_list[].location 位置
* @return string info[0].dynamic_list[].datatime 时间
* @return string info[0].dynamic_list[].skillid 技能ID0为无技能
* @return object info[0].dynamic_list[].skillinfo 技能信息
* @return string info[0].dynamic_list[].skillinfo.method 方式
* @return string info[0].dynamic_list[].skillinfo.name 技能名称
* @return string info[0].dynamic_list[].skillinfo.thumb 技能图标
* @return string info[0].dynamic_list[].skillinfo.coin 价格
* @return array info[0].userlist 用户列表
* @return string info[0].userlist[].user_nickname 昵称
* @return string info[0].userlist[].avatar 头像
* @return string info[0].userlist[].sex 性别
* @return string info[0].userlist[].age 年龄
* @return string info[0].userlist[].addr 地址
* @return string info[0].userlist[].profession 职业
* @return array info[0].userlist[].list 技能
* @return string info[0].userlist[].list[].name 名称
* @return string info[0].userlist[].list[].colour_font 字颜色
* @return string info[0].userlist[].list[].colour_bg 背景颜色
* @return string msg 提示信息
*/
public function getIndex() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid = \App\checkNull($this->uid);
/* 技能 */
$Domain_skill = new Domain_Skill();
$skilllist = $Domain_skill->getSkillList();
$info['skilllist']=$skilllist;
/* 轮播 */
$domain = new Domain_Home();
$silidelist = $domain->getSilide();
$info['silidelist']=$silidelist;
/* 用户列表 */
$list=$domain->getUsers($uid);
$info['userlist']=$list;
$rs['info'][0] = $info;
return $rs;
}
/**
* 用户列表
* @desc 用于获取用户列表(分页)
* @return int code 操作码0表示成功
* @return array info
* @return string info[].user_nickname 昵称
* @return string info[].avatar 头像
* @return string info[].sex 性别
* @return string info[].age 年龄
* @return string info[].addr 地址
* @return string info[].profession 职业
* @return array info[].list 技能
* @return string info[].list[].name 名称
* @return string info[].list[].colour_font 字颜色
* @return string info[].list[].colour_bg 背景颜色
* @return string msg 提示信息
*/
public function getUsers() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid = \App\checkNull($this->uid);
$p = \App\checkNull($this->p);
/* 用户列表 */
$domain = new Domain_Home();
$list=$domain->getUsers($uid,$p);
$rs['info'] = $list;
return $rs;
}
/**
* 搜索
* @desc 用于获取搜索信息
* @return int code 操作码0表示成功
* @return array info
* @return array info[0].skilllist 技能列表
* @return string info[0].skilllist[].id
* @return string info[0].skilllist[].name 技能名
* @return string info[0].skilllist[].thumb 图标
* @return array info[0].list 用户列表
* @return string info[0].list[].id 昵称
* @return string info[0].list[].user_nickname 昵称
* @return string info[0].list[].avatar 头像
* @return string info[0].list[].sex 性别
* @return string info[0].list[].age 年龄
* @return string msg 提示信息
*/
public function search() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$keyword = \App\checkNull($this->keyword);
if($keyword==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('请输入关键词');
return $rs;
}
/* 技能 */
$Domain_skill = new Domain_Skill();
$skilllist = $Domain_skill->getSkillList();
foreach($skilllist as $k=>$v){
if(!strstr($v['name'],$keyword)){
unset($skilllist[$k]);
}
}
$skilllist=array_values($skilllist);
$info['skilllist']=$skilllist;
/* 用户列表 */
$domain = new Domain_Home();
$list=$domain->searchUser($keyword);
$info['list']=$list;
$rs['info'][0] = $info;
return $rs;
}
/**
* 搜索用户列表
* @desc 用于获取搜索用户列表(分页)
* @return int code 操作码0表示成功
* @return array info
* @return string info[].id
* @return string info[].user_nickname 昵称
* @return string info[].avatar 头像
* @return string info[].sex 性别
* @return string info[].age 年龄
* @return string msg 提示信息
*/
public function searchMore() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$keyword = \App\checkNull($this->keyword);
if($keyword==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('请输入关键词');
return $rs;
}
/* 用户列表 */
$domain = new Domain_Home();
$list=$domain->searchUser($keyword);
$rs['info'] = $list;
return $rs;
}
}

View File

@ -0,0 +1,64 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\Im as Domain_Im;
/**
* 私信
*/
class Im extends Api {
public function getRules() {
return array(
'getSysNotice' => array(
'p' => array('name' => 'p', 'type' => 'string', 'desc' => '页码'),
),
);
}
/**
* 系统通知
* @desc 用于获取系统通知
* @return int code 操作码0表示成功
* @return array info 列表
* @return string info[].content 信息内容
* @return string info[].addtime 时间
* @return string msg 提示信息
*/
public function getSysNotice() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$p=\App\checkNull($this->p);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Im();
$list = $domain->getSysNotice($uid,$p);
$rs['info']=$list;
return $rs;
}
}

View File

@ -0,0 +1,306 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\Login as Domain_Login;
/**
* 注册、登录
*/
if (!session_id()) session_start();
class Login extends Api {
public function getRules() {
return array(
'login' => array(
'username' => array('name' => 'username', 'type' => 'string', 'desc' => '用户名'),
'code' => array('name' => 'code', 'type' => 'string', 'desc' => '验证码'),
'country_code' => array('name' => 'country_code', 'type' => 'string', 'desc' => '账号-区号'),
'source' => array('name' => 'source', 'type' => 'int', 'default'=>'0', 'desc' => '来源设备,0web1android2ios3小程序'),
),
'getCode' => array(
'account' => array('name' => 'account', 'type' => 'string', 'desc' => '手机号码'),
'country_code' => array('name' => 'country_code', 'type' => 'string', 'desc' => '区号'),
'sign' => array('name' => 'sign', 'type' => 'string', 'default'=>'', 'desc' => '签名'),
),
'getCountrys'=>array(
'field' => array('name' => 'field', 'type' => 'string', 'default'=>'', 'desc' => '搜索json串'),
),
);
}
/**
* 登录方式开关信息
* @desc 用于获取登录方式开关信息
* @return int code 操作码0表示成功
* @return array info
* @return string info[][0] 登录方式标识
* @return string msg 提示信息
*/
public function getLoginType() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$info = \App\getConfigPub();
$configpri=\App\getConfigPri();
//登录弹框那个地方
$login_alert=array(
'title'=>$info['login_alert_title'],
'content'=>$info['login_alert_content'],
'login_title'=>$info['login_clause_title'],
'message'=>array(
array(
'title'=>$info['login_service_title'],
'url'=>\App\get_upload_path($info['login_service_url']),
),
array(
'title'=>$info['login_private_title'],
'url'=>\App\get_upload_path($info['login_private_url']),
),
)
);
$login_type=$configpri['login_type'];
foreach ($login_type as $k => $v) {
if($v=='ios'){
unset($login_type[$k]);
break;
}
}
$login_type=array_values($login_type);
$rs['info'][0]['login_alert'] = $login_alert;
$rs['info'][0]['login_type'] = $login_type;
$rs['info'][0]['login_type_ios'] = $configpri['login_type'];
return $rs;
}
/**
* 登陆
* @desc 用于用户登陆信息
* @return int code 操作码0表示成功
* @return array info 用户信息
* @return string info[0].id 用户ID
* @return string info[0].user_nickname 昵称
* @return string info[0].avatar 头像
* @return string info[0].avatar_thumb 头像缩略图
* @return string info[0].sex 性别
* @return string info[0].signature 签名
* @return string info[0].coin 用户余额
* @return string info[0].login_type 注册类型
* @return string info[0].level 等级
* @return string info[0].level_anchor 主播等级
* @return string info[0].birthday 生日
* @return string info[0].age 年龄
* @return string info[0].token 用户Token
* @return string info[0].isauth 是否认证0否1是
* @return string info[0].usersig IM签名
* @return string msg 提示信息
*/
public function login() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$username = \App\checkNull($this->username);
$code = \App\checkNull($this->code);
$country_code = \App\checkNull($this->country_code);
$source = \App\checkNull($this->source);
if($username==''){
$rs['code'] = 995;
$rs['msg'] = \PhalApi\T('请输入手机号');
return $rs;
}
if($country_code!=$_SESSION['reg_country_code']){
$rs['code'] = 1004;
$rs['msg'] = '国家区号不一致';
return $rs;
}
if($code==''){
$rs['code'] = 996;
$rs['msg'] = \PhalApi\T('请输入验证码');
return $rs;
}
if(!isset($_SESSION['reg_account']) || !$_SESSION['reg_account'] || !isset($_SESSION['reg_code']) || !$_SESSION['reg_code'] ){
$rs['code'] = 996;
$rs['msg'] = \PhalApi\T('请先获取验证码');
return $rs;
}
if(time() - $_SESSION['reg_expiretime'] > 5*60){
$rs['code'] = 996;
$rs['msg'] = \PhalApi\T('验证码已过期,请重新获取');
return $rs;
}
if($_SESSION['reg_account']!=$username){
$rs['code'] = 995;
$rs['msg'] = \PhalApi\T('手机号码错误');
return $rs;
}
if($_SESSION['reg_code']!=$code){
$rs['code'] = 996;
$rs['msg'] = \PhalApi\T('验证码错误');
return $rs;
}
$domain = new Domain_Login();
$info = $domain->userLogin($username,$source);
return $info;
}
/**
* 获取注册验证码
* @desc 用于注册获取验证码
* @return int code 操作码0表示成功,2发送失败
* @return array info
* @return string msg 提示信息
*/
public function getCode() {
$rs = array('code' => 0, 'msg' => \PhalApi\T('发送成功,请注意查收'), 'info' => array());
$account = \App\checkNull($this->account);
$country_code = \App\checkNull($this->country_code);
$sign = \App\checkNull($this->sign);
if($account==''){
$rs['code']=995;
$rs['msg']=\PhalApi\T('请输入手机号');
return $rs;
}
$isok=\App\checkMobile($account,$country_code);
if($isok==1001){
$rs['code']=1001;
$rs['msg']=\PhalApi\T('国际/港澳台不支持国内区号');
return $rs;
}else if($isok==1002){
$rs['code']=1002;
$rs['msg']='国内不支持国际/港澳台区号';
return $rs;
}
if(!$isok){
$rs['code']=995;
$rs['msg']=\PhalApi\T('请输入正确的手机号');
return $rs;
}
$checkdata=array(
'account'=>$account
);
if(isset($_SESSION['reg_account']) && $_SESSION['reg_account']==$account && isset($_SESSION['reg_expiretime']) && $_SESSION['reg_expiretime']> time() ){
$rs['code']=996;
$rs['msg']=\PhalApi\T('验证码5分钟有效请勿多次发送');
return $rs;
}
$code = \App\random(6);
/* 发送验证码 */
$result=\App\sendCode($account,$code,$country_code);
if($result['code']==0){
$_SESSION['reg_account'] = $account;
$_SESSION['reg_country_code'] = $country_code;
$_SESSION['reg_code'] = $code;
$_SESSION['reg_expiretime'] = time() +60*5;
}else if($result['code']==667){
$_SESSION['reg_account'] = $account;
$_SESSION['reg_country_code'] = $country_code;
$_SESSION['reg_code'] = $result['msg'];
$_SESSION['reg_expiretime'] = time() +60*5;
$rs['code']=1002;
$rs['msg']=\PhalApi\T('验证码为:{n}',[ 'n'=>$result['msg'] ]);
}else{
$rs['code']=1002;
$rs['msg']=$result['msg'];
}
return $rs;
}
/*
* 获取国家列表
* @desc 用于获取国家列表
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].id 视频记录ID
* @return string msg 提示信息
*/
public function getCountrys() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$field=\App\checkNull($this->field);
$key='getCountrys';
$info=\App\getcaches($key);
if(!$info){
$city=API_ROOT.'/../PhalApi/config/country.json';//文件存放目录
// 从文件中读取数据到PHP变量
$json_string = file_get_contents($city);
// 用参数true把JSON字符串强制转成PHP数组
$data = json_decode($json_string, true);
$info=$data['country']; //国家
\App\setcaches($key,$info);
}
if($field){
$rs['info']=$this->array_searchs($field,$info);
return $rs;
}
$rs['info']=$info;
return $rs;
}
function array_searchs($field,$data) {
$arr=$result=array();
foreach($data as $k => $v){
$lists=$v['lists'];
foreach ($lists as $key => $value) {
if(strstr($value['name'], $field) !== false){
array_push($arr, $value);
}
}
foreach ($arr as $key => $value) {
if(array_key_exists($value,$lists)){
array_push($result, $lists[$value]);
}
}
}
return $arr;
}
}

View File

@ -0,0 +1,725 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\Orders as Domain_Orders;
/**
* 订单
*/
class Orders extends Api {
public function getRules() {
return array(
'getOrdersMore' => array(
'p' => array('name' => 'p', 'type' => 'int', 'default'=>'1', 'desc' => '页码'),
),
'getPay' => array(
'type' => array('name' => 'type', 'type' => 'int','desc' => 'APP类型1是安卓2是IOS'),
),
'checkOrder' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单号'),
),
'setOrder' => array(
'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'desc' => '主播ID'),
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
'type' => array('name' => 'type', 'type' => 'int', 'desc' => '时间类型0今天1明天2后天'),
'svctm' => array('name' => 'svctm', 'type' => 'string', 'desc' => '时间 H:i'),
'nums' => array('name' => 'nums', 'type' => 'int', 'desc' => '数量'),
'des' => array('name' => 'des', 'type' => 'string', 'desc' => '备注'),
'paytype' => array('name' => 'paytype', 'type' => 'int', 'default'=>'0', 'desc' => '支付方式0余额'),
),
'getOrderDetail' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单号'),
),
'getOrderDetails' => array(
'orderids' => array('name' => 'orderids', 'type' => 'string', 'desc' => '订单号,多个用,拼接'),
),
'cancelOrder' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单号'),
'reason' => array('name' => 'reason', 'type' => 'string', 'desc' => '原因ID,多个用,拼接'),
),
'receiptOrder' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单号'),
),
'refuseOrder' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单号'),
),
'completeOrder' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单号'),
),
'getOrdering' => array(
'touid' => array('name' => 'touid', 'type' => 'int', 'desc' => '对方ID'),
),
'upReceptStatus' => array(
'orderid' => array('name' => 'orderid', 'type' => 'int', 'desc' => '订单号'),
'recept_status' => array('name' => 'recept_status', 'type' => 'int', 'desc' => '状态::-1已申请立即服务0默认倒计时陪玩状态;1拒绝立即服务2同意立即服务'),
),
'getReceptDetails' => array(
'orderids' => array('name' => 'orderids', 'type' => 'string', 'desc' => '订单号,多个用,拼接'),
),
);
}
/**
* 订单列表
* @desc 用于获取订单列表
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return array info[0].listing 进行中的订单
* @return string info[0].listing[].id 订单ID
* @return string info[0].listing[].skillid 技能ID
* @return string info[0].listing[].total 总价
* @return string info[0].listing[].fee 手续费
* @return string info[0].listing[].profit 预计收益
* @return string info[0].listing[].des 订单备注
* @return string info[0].listing[].status 订单状态 -4 已超时 -3 已拒绝-2 完成 -1取消 0 待支付 1待接单 2已接单
* @return object info[0].listing[].userinfo 要显示的用户信息
* @return string info[0].listing[].iscommnet 是否评论0否1是
* @return object info[0].listing[].comment 评论
* @return string info[0].listing[].comment.content 评论内容
* @return string info[0].listing[].comment.star 星级
* @return array info[0].listing[].comment.label_a 标签列表
* @return string info[0].listing[].comment.label_a[] 标签
* @return object info[0].listing[].skill 技能
* @return string info[0].listing[].skill.id 技能ID0表示已移除 不能再次下单
* @return string info[0].listing[].skill.name 名字
* @return string info[0].listing[].skill.method 单位
* @return string info[0].listing[].skill.thumb 图片
* @return object info[0].listing[].auth 技能认证信息
* @return string info[0].listing[].auth.switch 开关0关1开
* @return string info[0].listing[].auth.coin 价格
* @return array info[0].list 历史订单
* @return string info[0].list[].id 订单ID
* @return string info[0].list[].skillid 技能ID
* @return string info[0].list[].total 总价
* @return string info[0].list[].fee 手续费
* @return string info[0].list[].profit 预计收益
* @return string info[0].list[].des 订单备注
* @return string info[0].list[].status 订单状态 -4 已超时 -3 已拒绝-2 完成 -1取消 0 待支付 1待接单 2已接单
* @return object info[0].list[].userinfo 要显示的用户信息
* @return string info[0].list[].iscommnet 是否评论0否1是
* @return object info[0].list[].comment 评论
* @return string info[0].list[].comment.content 评论内容
* @return string info[0].list[].comment.star 星级
* @return array info[0].list[].comment.label_a 标签列表
* @return string info[0].list[].comment.label_a[] 标签
* @return object info[0].list[].skill 技能
* @return string info[0].list[].skill.id 技能ID0表示已移除 不能再次下单
* @return string info[0].list[].skill.name 名字
* @return string info[0].list[].skill.method 单位
* @return string info[0].list[].skill.thumb 图片
* @return object info[0].list[].auth 技能认证信息
* @return string info[0].list[].auth.switch 开关0关1开
* @return string info[0].list[].auth.coin 价格
* @return string msg 提示信息
*/
public function getOrders() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Orders();
$listing = $domain->getOrdersing($uid);
$list = $domain->getOrders($uid,1);
$info['listing']=$listing;
$info['list']=$list;
$rs['info'][0] =$info;
return $rs;
}
/**
* 历史订单列表
* @desc 用于获取历史订单列表(分页)
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string info[].id 订单ID
* @return string info[].skillid 技能ID
* @return string info[].total 总价
* @return string info[].fee 手续费
* @return string info[].profit 预计收益
* @return string info[].des 订单备注
* @return string info[].status 订单状态 -4 已超时 -3 已拒绝-2 完成 -1取消 0 待支付 1待接单 2已接单
* @return object info[].userinfo 要显示的用户信息
* @return string info[].iscommnet 是否评论0否1是
* @return object info[].comment 评论
* @return string info[].comment.content 评论内容
* @return string info[].comment.star 星级
* @return array info[].comment.label_a 标签列表
* @return string info[].comment.label_a[] 标签
* @return object info[].skill 技能
* @return string info[].skill.id 技能ID0表示已移除 不能再次下单
* @return string info[].skill.name 名字
* @return string info[].skill.method 单位
* @return string info[].skill.thumb 图片
* @return object info[].auth 技能认证信息
* @return string info[].auth.switch 开关0关1开
* @return string info[].auth.coin 价格
* @return string msg 提示信息
*/
public function getOrdersMore() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$p=\App\checkNull($this->p);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Orders();
$info = $domain->getOrders($uid,$p);
$rs['info'] =$info;
return $rs;
}
/**
* 获取支付
* @desc 用于获取下单页面支付列表
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string info[].id 订单ID
* @return string info[].skillid 技能ID
* @return string info[].total 总价
* @return string info[].des 订单备注
* @return string msg 提示信息
*/
public function getPay() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$type=\App\checkNull($this->type);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$userinfo=\App\getUserCoin($uid);
$configpri=\App\getConfigPri();
$paylist=[];
$paylist[]=[
'id'=>'0',
'name'=>\PhalApi\T('余额支付'),
'thumb'=>\App\get_upload_path("/static/app/pay/coin.png"),
];
$userinfo['paylist'] =$paylist;
$rs['info'][0] =$userinfo;
return $rs;
}
/**
* 获取订单状态
* @desc 用于获取订单状态
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string info[0].status 订单状态,-4已超时-3拒绝-2已完成-1取消0待支付1已支付2已接单
* @return string msg 提示信息
*/
public function checkOrder() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderid=\App\checkNull($this->orderid);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
if($orderid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$data=[
'uid'=>$uid,
'id'=>$orderid,
];
$domain = new Domain_Orders();
$res = $domain->checkOrder($data);
if(!$res){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$info['status']=$res['status'];
$rs['info'][0] = $info;
return $rs;
}
/**
* 下单
* @desc 用于下单
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string info[0].orderno 订单号
* @return string info[0].orderid 订单ID
* @return string info[0].total 支付价格
* @return object info[0].ali 支付宝信息
* @return string info[0].ali.partner 合作者ID
* @return string info[0].ali.seller_id 账号
* @return string info[0].ali.key PKCS8密钥
* @return object info[0].wx 微信信息
* @return string info[0].wx.appid 微信Appid
* @return string info[0].wx.noncestr 随机数
* @return string info[0].wx.package 固定数据
* @return string info[0].wx.partnerid 商户ID
* @return string info[0].wx.prepayid 支付ID
* @return string info[0].wx.timestamp 时间戳
* @return string msg 提示信息
*/
public function setOrder() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$liveuid=\App\checkNull($this->liveuid);
$skillid=\App\checkNull($this->skillid);
$type=\App\checkNull($this->type);
$svctm=\App\checkNull($this->svctm);
$nums=\App\checkNull($this->nums);
$des=\App\checkNull($this->des);
$paytype=\App\checkNull($this->paytype);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
if($liveuid<1 || $skillid<1 || $type<0 || $type>2 || $svctm=='' || $nums<1 || $paytype<0){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$islimit=\App\getBanstatus($uid,"1");
if($islimit && $islimit['isbanorder']=='1'){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('取消次数已达上限,'.$islimit['endtime'].'前禁止下单');
return $rs;
}
$livelimit=\App\getBanstatus($liveuid,"0");
if($livelimit && $livelimit['isbanorder']=='1'){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('对方截止到'.$livelimit['endtime'].'已被禁止接单');
return $rs;
}
$data=[
'uid'=>$uid,
'liveuid'=>$liveuid,
'skillid'=>$skillid,
'type'=>$type,
'svctm'=>$svctm,
'nums'=>$nums,
'des'=>$des,
'paytype'=>$paytype,
];
$domain = new Domain_Orders();
$res = $domain->checkset($data);
return $res;
}
/**
* 订单详情
* @desc 用于获取订单详情
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function getOrderDetail() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderid=\App\checkNull($this->orderid);
if($orderid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Orders();
$info = $domain->getOrderDetail($uid,$orderid);
if(!$info){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('订单信息有误');
return $rs;
}
$rs['info'][0]=$info;
return $rs;
}
/**
* 多个订单详情
* @desc 用于获取订单详情,一次获取多个订单
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function getOrderDetails() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderids=\App\checkNull($this->orderids);
if($orderids<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$list=[];
$domain = new Domain_Orders();
$orderids_a=preg_split('/|,/',$orderids);
$orderids_a=array_filter($orderids_a);
foreach($orderids_a as $k=>$v){
$info = $domain->getOrderDetail($uid,$v);
if($info){
$list[]=$info;
}
}
$rs['info']=$list;
return $rs;
}
/**
* 取消原因
* @desc 用于获取订单取消原因
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function getCancelList() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$domain = new Domain_Orders();
$list = $domain->getCancelList();
$rs['info']=$list;
return $rs;
}
/**
* 取消订单
* @desc 用于下单用户取消订单
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function cancelOrder() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderid=\App\checkNull($this->orderid);
$reason=\App\checkNull($this->reason);
if($orderid<1 || $reason==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$islimit=\App\cancel_order_limit($uid);
if($islimit){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('可用取消次数已达上限');
return $rs;
}
$domain = new Domain_Orders();
$info = $domain->cancelOrder($uid,$orderid,$reason);
return $info;
}
/**
* 接单
* @desc 用于接单
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function receiptOrder() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderid=\App\checkNull($this->orderid);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Orders();
$info = $domain->receiptOrder($uid,$orderid);
return $info;
}
/**
* 拒接
* @desc 用于拒绝接单
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function refuseOrder() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderid=\App\checkNull($this->orderid);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Orders();
$info = $domain->refuseOrder($uid,$orderid);
return $info;
}
/**
* 完成订单
* @desc 用于确认完成订单
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function completeOrder() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderid=\App\checkNull($this->orderid);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Orders();
$info = $domain->completeOrder($uid,$orderid);
return $info;
}
/**
* 获取进行中的订单
* @desc 用于获取用户间正在进行的订单信息
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string info[0].isexist 是否有订单0否1是
* @return object info[0].order 订单信息
* @return string info[0].order.iscommnet 用户是否评论主播0否1是
* @return object info[0].order.comment 评论内容
* @return string info[0].order.isevaluate 主播是否评价用户0否1是
* @return object info[0].order.evaluate 评价内容
* @return string msg 提示信息
*/
public function getOrdering() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$touid=\App\checkNull($this->touid);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Orders();
$info = $domain->getOrdering($uid,$touid);
$rs['info'][0]=$info;
return $rs;
}
/**
* 接单后:更改服务状态
* @desc 用于 接单后:更改服务状态
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function upReceptStatus() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderid=\App\checkNull($this->orderid);
$recept_status=\App\checkNull($this->recept_status);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Orders();
$info = $domain->upReceptStatus($uid,$orderid,$recept_status);
return $info;
}
/**
* 多个已接单:服务状态订单详情
* @desc 用于获取 已接单:服务状态订单详情,一次获取多个订单
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return string msg 提示信息
*/
public function getReceptDetails() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$orderids=\App\checkNull($this->orderids);
if($orderids<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$list=[];
$domain = new Domain_Orders();
$orderids_a=preg_split('/|,/',$orderids);
$orderids_a=array_filter($orderids_a);
foreach($orderids_a as $k=>$v){
$info = $domain->getReceptOrderDetail($uid,$v);
if($info){
$list[]=$info;
}
}
$rs['info']=$list;
return $rs;
}
}

View File

@ -0,0 +1,46 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
/**
* 默认接口服务类
* @author: dogstar <chanzonghuang@gmail.com> 2014-10-04
*/
class Site extends Api {
public function getRules() {
return array(
'index' => array(
'username' => array('name' => 'username', 'default' => '', 'desc' => '用户名'),
),
);
}
/**
* 默认接口服务
* @desc 默认接口服务,当未指定接口服务时执行此接口服务
* @return string title 标题
* @return string content 内容
* @return string version 版本格式X.X.X
* @return int time 当前时间戳
* @exception 400 非法请求,参数传递错误
*/
public function index() {
return array(
'title' => 'Hello ' . $this->username,
'version' => PHALAPI_VERSION,
'time' => $_SERVER['REQUEST_TIME'],
);
}
}

View File

@ -0,0 +1,581 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\Skill as Domain_Skill;
use App\Domain\User as Domain_User;
/**
* 技能
*/
class Skill extends Api {
public function getRules() {
return array(
'setSwitch' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
'isswitch' => array('name' => 'isswitch', 'type' => 'int', 'desc' => '开关0关1开'),
),
'getCoins' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
),
'upSkill' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
'fields' => array('name' => 'fields', 'type' => 'string', 'desc' => 'json'),
),
'getLevel' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
),
'getLabel' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
),
'getUserList' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
'order' => array('name' => 'order', 'type' => 'int', 'default'=>'0', 'desc' => '排序0智能1最新'),
'sex' => array('name' => 'sex', 'type' => 'int', 'default'=>'0', 'desc' => '性别0不限1男2女'),
'level' => array('name' => 'level', 'type' => 'int', 'default'=>'0', 'desc' => '段位ID,不选为0'),
'voice' => array('name' => 'voice', 'type' => 'int', 'default'=>'0', 'desc' => '语音0不限1有'),
),
'getSkillHome' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'desc' => '主播ID'),
),
'getSkillInfo' => array(
'skillid' => array('name' => 'skillid', 'type' => 'int', 'desc' => '技能ID'),
'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'desc' => '主播ID'),
),
'getSkillAuth' => array(
'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'desc' => '主播ID'),
),
'getMyskillList' => array(
),
);
}
/**
* 全部分类
* @desc 用于获取全部分类
* @return int code 操作码0表示成功
* @return array info 列表
* @return string info[].id 分类ID
* @return string info[].name 分类名
* @return array info[].list 技能列表
* @return string info[].list[].id 技能ID
* @return string info[].list[].name 技能名
* @return string info[].list[].thumb 图标
* @return string msg 提示信息
*/
public function getAll() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$domain = new Domain_Skill();
$list = $domain->getAll();
$rs['info']=$list;
return $rs;
}
/**
* 选择技能认证
* @desc 用于获取技能信息
* @return int code 操作码0表示成功
* @return array info 列表
* @return string info[].id 分类ID
* @return string info[].name 技能名
* @return string info[].thumb 图标
* @return string info[].status 状态 -1未申请 0审核中1通过2拒绝
* @return string msg 提示信息
*/
public function getUserSkill() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Skill();
$list = $domain->getUserSkill($uid);
$rs['info']=$list;
return $rs;
}
/**
* 我的技能
* @desc 用于获取技能信息
* @return int code 操作码0表示成功
* @return array info 列表
* @return string info[].id
* @return string info[].skillid 技能ID
* @return string info[].switch 开关0关1开
* @return string info[].thumb 截图
* @return string info[].coin 价格
* @return string info[].voice 语音
* @return string info[].des 描述
* @return string info[].level 段位
* @return array info[].label_a 标签列表
* @return string info[].label_a[] 标签
* @return object info[].skill 技能信息
* @return object info[].skill.name 技能名
* @return object info[].skill.thumb 图标
* @return object info[].skill.method 单位
* @return string msg 提示信息
*/
public function getMySkill() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Skill();
$list = $domain->getMySkill($uid);
$rs['info']=$list;
return $rs;
}
/**
* 技能开关
* @desc 用于开启、关闭技能
* @return int code 操作码0表示成功
* @return array info 列表
* @return string msg 提示信息
*/
public function setSwitch() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$skillid=\App\checkNull($this->skillid);
$isswitch=\App\checkNull($this->isswitch);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain1 = new Domain_User();
$isauth = $domain1->isauth($uid);
if(!$isauth){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('实名认证未通过');
return $rs;
}
$data=[
'switch'=>$isswitch
];
$domain = new Domain_Skill();
$info = $domain->setSwitch($uid,$skillid,$data);
return $info;
}
/**
* 价格列表
* @desc 用于获取价格列表
* @return int code 操作码0表示成功
* @return array info
* @return string msg 提示信息
*/
public function getCoins() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$skillid=\App\checkNull($this->skillid);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Skill();
$info = $domain->getCoins($uid,$skillid);
$rs['info']=$info;
return $rs;
}
/**
* 价格说明
* @desc 用于查看价格说明
* @return int code 操作码0表示成功
* @return array info
* @return string info[].coin 价格
* @return string info[].orders 接单数
* @return string msg 提示信息
*/
public function getCoinInfo() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$domain = new Domain_Skill();
$coinlist = $domain->getCoinList();
$keys=array_keys($coinlist);
$end=end($keys);
$orders='0';
$coin='0';
$list=[];
foreach($coinlist as $k=>$v ){
$data=[];
if($orders<$v['orders']){
$data['coin']=(string)$coin;
$data['orders']=(string)$orders;
$list[]=$data;
}
if($k==$end){
$data['coin']=(string)$v['coin'];
$data['orders']=(string)$v['orders'];
$list[]=$data;
}
$orders=$v['orders'];
$coin=$v['coin'];
}
$rs['info']=$list;
return $rs;
}
/**
* 更新技能配置
* @desc 用于更新技能配置
* @return int code 操作码0表示成功
* @return array info 列表
* @return string msg 提示信息
*/
public function upSkill() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$skillid=\App\checkNull($this->skillid);
$fields=$this->fields;
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$fields_a=json_decode($fields,true);
$domain = new Domain_Skill();
$res = $domain->upSkill($uid,$skillid,$fields_a);
return $res;
}
/**
* 技能段位
* @desc 用于获取技能段位
* @return int code 操作码0表示成功
* @return array info 列表
* @return string info[].levelid
* @return string info[].name 段位名
* @return string msg 提示信息
*/
public function getLevel() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$skillid = \App\checkNull($this->skillid);
if($skillid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$domain = new Domain_Skill();
$list = $domain->getLevel($skillid);
foreach($list as $k=>$v){
$v['id']=$v['levelid'];
$list[$k]=$v;
}
$rs['info']=$list;
return $rs;
}
/**
* 技能标签
* @desc 用于获取技能标签
* @return int code 操作码0表示成功
* @return array info 列表
* @return string info[].id
* @return string info[].name 标签
* @return string msg 提示信息
*/
public function getLabel() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$skillid = \App\checkNull($this->skillid);
if($skillid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$domain = new Domain_Skill();
$list = $domain->getLabel($skillid);
$rs['info']=$list;
return $rs;
}
/**
* 某技能下用户
* @desc 用于获取全部分类
* @return int code 操作码0表示成功
* @return array info 列表
* @return string info[].id
* @return string info[].skillid 技能ID
* @return string info[].method 单位
* @return string info[].level 段位
* @return string info[].star_level 星级
* @return string info[].orders 接单量
* @return object info[].userinfo 用户信息
* @return array info[].label_a 标签列表
* @return string info[].label_a[] 标签
* @return string msg 提示信息
*/
public function getUserList() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid = \App\checkNull($this->uid);
$skillid = \App\checkNull($this->skillid);
$order = \App\checkNull($this->order);
$sex = \App\checkNull($this->sex);
$level = \App\checkNull($this->level);
$voice = \App\checkNull($this->voice);
if($skillid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$domain = new Domain_Skill();
$list = $domain->getUserList($uid,$skillid,$order,$sex,$level,$voice);
$rs['info']=$list;
return $rs;
}
/**
* 技能主页
* @desc 用于获取技能主页信息
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].isattent 是否关注0否1是
* @return object info[0].skill 技能信息
* @return string info[0].skill.method 单位
* @return array info[0].authinfo 技能认证信息
* @return string info[0].authinfo.thumb 截图
* @return string info[0].authinfo.level 段位
* @return string info[0].authinfo.coin 价格
* @return string info[0].authinfo.voice 语音介绍
* @return string info[0].authinfo.des 介绍
* @return string info[0].authinfo.orders 接单数
* @return string info[0].authinfo.stars 星级数字
* @return string info[0].authinfo.star_level 星级
* @return array info[0].authinfo.label_a 标签列表
* @return string info[0].authinfo.label_a[] 标签
* @return string info[0].comment_nums 评论总数
* @return array info[0].label_list 评论标签统计
* @return string info[0].label_list[].label 标签
* @return string info[0].label_list[].nums 数量
* @return array info[0].comment_list 评论列表
* @return object info[0].comment_list[].userinfo 评论用户信息
* @return string info[0].comment_list[].content 内容
* @return string info[0].comment_list[].star 星级
* @return string info[0].comment_list[].add_time 时间
* @return array info[0].comment_list[].label_a 评论标签
* @return string info[0].comment_list[].label_a[] 标签
* @return string msg 提示信息
*/
public function getSkillHome() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid = \App\checkNull($this->uid);
$skillid = \App\checkNull($this->skillid);
$liveuid = \App\checkNull($this->liveuid);
if($skillid<1 || $liveuid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$domain = new Domain_Skill();
$info = $domain->getSkillHome($uid,$liveuid,$skillid);
return $info;
}
/**
* 用户某技能信息
* @desc 用于获取用户某技能信息
* @return int code 操作码0表示成功
* @return array info
* @return object info[0].skill 技能信息
* @return string info[0].skill.method 单位
* @return array info[0].authinfo 技能认证信息
* @return string info[0].authinfo.thumb 截图
* @return string info[0].authinfo.level 段位
* @return string info[0].authinfo.coin 价格
* @return string info[0].authinfo.voice 语音介绍
* @return string info[0].authinfo.des 介绍
* @return string info[0].authinfo.orders 接单数
* @return string info[0].authinfo.stars 星级数字
* @return string info[0].authinfo.star_level 星级
* @return array info[0].authinfo.label_a 标签列表
* @return string info[0].authinfo.label_a[] 标签
* @return string msg 提示信息
*/
public function getSkillInfo() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$skillid = \App\checkNull($this->skillid);
$liveuid = \App\checkNull($this->liveuid);
if($skillid<1 || $liveuid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$domain = new Domain_Skill();
$info = $domain->getSkillInfo($liveuid,$skillid);
return $info;
}
/**
* 用户技能列表
* @desc 用于获取某用户技能列表
* @return int code 操作码0表示成功
* @return array info
* @return string info[].skillid 技能ID
* @return string info[].coin 价格
* @return string info[].method 单位
* @return string info[].skillname 技能名称
* @return string info[].level 段位
* @return string info[].orders 接单量
* @return string msg 提示信息
*/
public function getSkillAuth() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$liveuid = \App\checkNull($this->liveuid);
if( $liveuid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$where=[
'uid'=>$liveuid,
'status'=>'1',
'switch'=>'1',
];
$domain = new Domain_Skill();
$list = $domain->getSkillAuth($where);
$rs['info']=$list;
return $rs;
}
/** 我的技能列表
* @desc 用于获取技能信息
* @return int code 操作码0表示成功
* @return array info 列表
* @return string msg 提示信息
*/
public function getMyskillList() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_Skill();
$list = $domain->getMyskillList($uid);
$rs['info']=$list;
return $rs;
}
}

View File

@ -0,0 +1,156 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
/**
* 上传
*/
class Upload extends Api {
public function getRules() {
return array(
);
}
/**
* 获取七牛Token
* @desc 用于获取充值规则
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].token 七牛Token
* @return string msg 提示信息
*/
public function getQiniuToken() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$token = \PhalApi\DI()->qiniu->getToken();
$token2=\App\encryption($token);
$info['token']=$token2;
$rs['info'][0] =$info;
return $rs;
}
public function getQiniuTokenstr() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$token = \PhalApi\DI()->qiniu->getToken();
$token2=\App\encryption($token);
$info['token']=$token2;
$rs['info'][0] =$info;
return $token2;
}
/**
* 获取云存储方式、获取七牛上传验证token字符串、获取腾讯云存储相关配置信息
* @desc 用于获取云存储方式、获取七牛上传验证token字符串、获取腾讯云存储相关配置信息
* @return int code 操作码0表示成功
* @return string msg 提示信息
* @return array info 返回信息
*/
public function getCosInfo(){
$rs=array("code"=>0,"msg"=>"","info"=>array());
/* $uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
*/
//获取七牛信息
$qiniuToken=$this->getQiniuTokenstr();
//获取腾讯云存储配置信息
$configpri=\App\getConfigPri();
if(!$configpri['cloudtype']){
$rs['code']=1001;
$rs['msg']="无指定存储方式";
return $rs;
}
$space_host= \PhalApi\DI()->config->get('app.Qiniu.space_host');
$region= \PhalApi\DI()->config->get('app.Qiniu.region');
$qiniu_zone='';
// $zone=$configpri['zone'];
if($region=='z0'){
$qiniu_zone='qiniu_hd';
}else if($region=='z1'){
$qiniu_zone='qiniu_hb';
}else if($region=='z2'){
$qiniu_zone='qiniu_hn';
}else if($region=='na0'){
$qiniu_zone='qiniu_bm';
}else if($region=='as0'){
$qiniu_zone='qiniu_xjp';
}
// $qiniu_domain_url=$configpri['protocol']."://".$configpri['domain']."/";
$qiniuInfo=array(
'qiniuToken'=>$qiniuToken,
'qiniu_domain'=>$space_host,
'qiniu_zone'=>$qiniu_zone //华东:qiniu_hd 华北:qiniu_hb 华南:qiniu_hn 北美:qiniu_bm 新加坡:qiniu_xjp 不可随意更改app已固定好规则
);
$awsInfo=array(
'aws_bucket'=>$configpri['aws_bucket'],
'aws_region'=>$configpri['aws_region'],
'aws_identitypoolid'=>$configpri['aws_identitypoolid'],
);
$rs['info'][0]['qiniuInfo']=$qiniuInfo;
$rs['info'][0]['awsInfo']=$awsInfo;
$cloudtype="";
switch ($configpri['cloudtype']) {
case '1':
$cloudtype="qiniu";
break;
case '2':
$cloudtype="aws";
break;
}
$rs['info'][0]['cloudtype']=$cloudtype;
return $rs;
}
}

View File

@ -0,0 +1,731 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Api;
use PhalApi\Api;
use App\Domain\User as Domain_User;
use App\Domain\Skill as Domain_Skill;
use App\Domain\Home as Domain_Home;
/**
* 用户信息
*/
class User extends Api {
public function getRules() {
return array(
'getBaseInfo' => array(
'ios_version' => array('name' => 'ios_version', 'type' => 'string', 'default'=>'', 'desc' => 'IOS版本号'),
),
'setUserinfo' => array(
'fields' => array('name' => 'fields', 'type' => 'string', 'default'=>'', 'desc' => '修改信息json串'),
),
'upUserInfo' => array(
'fields' => array('name' => 'fields', 'type' => 'string', 'default'=>'', 'desc' => '修改信息json串'),
),
'setAttent' => array(
'touid' => array('name' => 'touid', 'type' => 'int', 'desc' => '对方ID'),
),
'getFollow' => array(
'touid' => array('name' => 'touid', 'type' => 'int', 'desc' => '对方ID'),
'p' => array('name' => 'p', 'type' => 'int', 'default'=>'1', 'desc' => '页码'),
),
'getFans' => array(
'touid' => array('name' => 'touid', 'type' => 'int', 'desc' => '对方ID'),
'p' => array('name' => 'p', 'type' => 'int', 'default'=>'1', 'desc' => '页码'),
),
'getHome' => array(
'touid' => array('name' => 'touid', 'type' => 'int', 'desc' => '对方ID'),
),
'checkAttent' => array(
'touid' => array('name' => 'touid', 'type' => 'int', 'desc' => '对方ID'),
),
'getRecom' => array(
'sex' => array('name' => 'sex', 'type' => 'int', 'defaulf'=>0, 'desc' => '性别0不限1男2女'),
'age' => array('name' => 'age', 'type' => 'int', 'defaulf'=>0, 'desc' => '年龄0不限1-702-803-904-005-10'),
'skillid' => array('name' => 'skillid', 'type' => 'int', 'defaulf'=>0, 'desc' => '技能ID'),
'p' => array('name' => 'p', 'type' => 'int', 'default'=>'1', 'desc' => '页码'),
),
'getFollowlist' => array(
'sex' => array('name' => 'sex', 'type' => 'int', 'defaulf'=>0, 'desc' => '性别0不限1男2女'),
'age' => array('name' => 'age', 'type' => 'int', 'defaulf'=>0, 'desc' => '年龄0不限1-702-803-904-005-10'),
'skillid' => array('name' => 'skillid', 'type' => 'int', 'defaulf'=>0, 'desc' => '技能ID'),
'p' => array('name' => 'p', 'type' => 'int', 'default'=>'1', 'desc' => '页码'),
),
'getAuthlist' => array(
'p' => array('name' => 'p', 'type' => 'int', 'default'=>'1', 'desc' => '页码'),
),
);
}
/**
* 判断token
* @desc 用于判断token
* @return int code 操作码0表示成功
* @return array info
* @return string msg 提示信息
*/
public function iftoken() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
return $rs;
}
/**
* 获取用户信息
* @desc 用于获取单个用户基本信息
* @return int code 操作码0表示成功 1表示用户不存在
* @return array info
* @return array info[0] 用户信息
* @return int info[0].id 用户ID
* @return string info[0].follows 关注数
* @return string info[0].fans 粉丝数
* @return string info[0].auth_nums 开启的技能数
* @return string info[0].profession 职业
* @return string info[0].school 学校
* @return string info[0].hobby 兴趣
* @return string info[0].voice 语音
* @return string info[0].age 年龄
* @return string info[0].constellation 星座
* @return string info[0].visitnums 来访量
* @return string info[0].viewnums 浏览量
* @return string info[0].newnums 新增来访量
* @return array info[0].list
* @return string info[0].list[].id
* @return string info[0].list[].name 名称
* @return string info[0].list[].thumb 图标
* @return string info[0].list[].href H5链接
* @return string msg 提示信息
*/
public function getBaseInfo() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_User();
$info = $domain->getBaseInfo($uid);
if(!$info){
$rs['code'] = 700;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$configpub=\App\getConfigPub();
$configpri=\App\getConfigPri();
/* 个人中心菜单 */
$list=array();
$list1=array();
$shelves=1;
$auth_nums='0';
$isauth=$domain->isauth($uid);
$Domain_Skill = new Domain_Skill();
$where=[];
$where['uid']=$uid;
$where['status']='1';
$isskillauth=$Domain_Skill->getSkillAuth($where);
$list1[]=array('id'=>'1','name'=>\PhalApi\T('订单中心'),'thumb'=>\App\get_upload_path("/static/app/person/order1.png"),'href'=>'' );
$list1[]=array('id'=>'3','name'=>\PhalApi\T('实名认证'),'thumb'=>\App\get_upload_path("/static/app/person/auth2.png"),'href'=>\App\get_upload_path("/appapi/auth/index") );
if($isskillauth){
foreach($isskillauth as $k=>$v){
if($v['switch']==1){
$auth_nums++;
}
}
$list1[]=array('id'=>'5','name'=>\PhalApi\T('我的技能'),'thumb'=>\App\get_upload_path("/static/app/person/skill1.png"),'href'=>'' );
}elseif($isauth==1){
$list1[]=array('id'=>'4','name'=>\PhalApi\T('申请大神'),'thumb'=>\App\get_upload_path("/static/app/person/skill1.png"),'href'=>'' );
}
$list1[]=array('id'=>'6','name'=>\PhalApi\T('个性设置'),'thumb'=>\App\get_upload_path("/static/app/person/setting1.png") ,'href'=>'');
$list[0]['title']=\PhalApi\T('');
$list[0]['list']=$list1;
$list[1]['title']=\PhalApi\T('我的钱包');
$list[1]['coin']=$info['coin'];
$list[1]['list']=$list2;
$info['list']=$list;
$info['auth_nums']=(string)$auth_nums;
$rs['info'][0] = $info;
return $rs;
}
/**
* 设置资料
* @desc 用于用户设置资料
* @return int code 操作码0表示成功
* @return array info
* @return string msg 提示信息
*/
public function setUserinfo() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$fields=$this->fields;
if($fields==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$fields_a=json_decode($fields,true);
if(!$fields_a){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
if( !isset($fields_a['avatar']) || $fields_a['avatar']=='' ){
$rs['code'] = 1003;
$rs['msg'] = \PhalApi\T('请上传头像');
return $rs;
}
if( !isset($fields_a['user_nickname']) || $fields_a['user_nickname']=='' ){
$rs['code'] = 1004;
$rs['msg'] = \PhalApi\T('请设置您的昵称');
return $rs;
}
if( !isset($fields_a['birthday']) || $fields_a['birthday']=='' ){
$rs['code'] = 1005;
$rs['msg'] = \PhalApi\T('请选择出生日期');
return $rs;
}
if( !isset($fields_a['sex']) || !$fields_a['sex'] ){
$rs['code'] = 1006;
$rs['msg'] = \PhalApi\T('请选择您的性别');
return $rs;
}
$domain = new Domain_User();
$info = $domain->upUserInfo($uid,$fields_a);
return $info;
}
/**
* 更新基本信息
* @desc 用于用户更新基本信息
* @return int code 操作码0表示成功
* @return array info
* @return string msg 提示信息
*/
public function upUserInfo() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$fields=$this->fields;
if($fields==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$fields_a=json_decode($fields,true);
if(!$fields_a){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
unset($fields_a['sex']);
$domain = new Domain_User();
$info = $domain->upUserInfo($uid,$fields_a);
return $info;
}
/**
* 设置、取消关注
* @desc 用于设置、取消关注
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].isattent 是否关注0否1是
* @return string msg 提示信息
*/
public function setAttent() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$touid=\App\checkNull($this->touid);
if($touid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
if($uid==$touid){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('不能关注自己');
return $rs;
}
$domain = new Domain_User();
$isattent = $domain->setAttent($uid,$touid);
$info['isattent']=$isattent;
$msg=\PhalApi\T('取消成功');
if($isattent==1){
$msg=\PhalApi\T('关注成功');
}
$rs['msg']=$msg;
$rs['info'][0]=$info;
return $rs;
}
/**
* 关注列表
* @desc 用于获取用户关注列表
* @return int code 操作码0表示成功
* @return array info
* @return object info[] 用户基本信息
* @return string info[].isattent 是否关注0否1是
* @return string msg 提示信息
*/
public function getFollow() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$touid=\App\checkNull($this->touid);
$p=\App\checkNull($this->p);
if($touid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$domain = new Domain_User();
$list = $domain->getFollow($uid,$touid,$p);
$rs['info']=$list;
return $rs;
}
/**
* 粉丝列表
* @desc 用于获取用户粉丝列表
* @return int code 操作码0表示成功
* @return array info
* @return object info[] 用户基本信息
* @return string info[].isattent 是否关注0否1是
* @return string msg 提示信息
*/
public function getFans() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$touid=\App\checkNull($this->touid);
$p=\App\checkNull($this->p);
if($touid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$domain = new Domain_User();
$list = $domain->getFans($uid,$touid,$p);
$rs['info']=$list;
return $rs;
}
/**
* 个人主页
* @desc 用于个人主页信息
* @return int code 操作码0表示成功
* @return array info 用户基本信息
* @return string info[].isattent 是否关注0否1是
* @return string info[].des 信息描述
* @return string info[].fans 粉丝数
* @return array info[].list 技能列表
* @return string msg 提示信息
*/
public function getHome() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$touid=\App\checkNull($this->touid);
if($uid<1 || $touid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$domain = new Domain_User();
$info = $domain->getHome($uid,$touid);
$rs['info'][0]=$info;
return $rs;
}
/**
* 检测关系
* @desc 用于检测两个用户间的关注情况
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].status 状态0表示未关注1表示我关注对方2表示对方关注我3表示互关
* @return string msg 提示信息
*/
public function checkAttent() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$touid=\App\checkNull($this->touid);
if($uid<1 || $token=='' || $touid<1){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_User();
$status = $domain->checkAttent($uid,$touid);
$rs['info'][0]['status']=$status;
return $rs;
}
/**
* 判断认证
* @desc 用于判断是否认证
* @return int code 操作码0表示成功
* @return array info
* @return string info[0].isauth 是否认证0否1是
* @return string msg 提示信息
*/
public function ifauth() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$domain = new Domain_User();
$isauth = $domain->isauth($uid);
$info['isauth']=$isauth;
$rs['info'][0]=$info;
return $rs;
}
/** 推荐列表
* @desc 用于获取用户 推荐列表
* @return int code 操作码0表示成功
* @return array info
* @return object info[] 用户基本信息
* @return string info[].isattent 是否关注0否1是
* @return string msg 提示信息
*/
public function getRecomBF() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$sex=\App\checkNull($this->sex);
$age=\App\checkNull($this->age);
$skillid=\App\checkNull($this->skillid);
$p=\App\checkNull($this->p);
if($uid=='' || $token=='' || $sex<0 || $sex>2 || $age<0 || $age>5 ){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$type=0;
$domain = new Domain_User();
$list = $domain->getList($uid,$sex,$age,$skillid,$p,$type);
$rs['info']=$list;
return $rs;
}
/** 推荐列表
* @desc 用于获取用户 推荐列表
* @return int code 操作码0表示成功
* @return array info
* @return object info[] 用户基本信息
* @return string info[].isattent 是否关注0否1是
* @return string msg 提示信息
*/
public function getRecom() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$sex=\App\checkNull($this->sex);
$age=\App\checkNull($this->age);
$skillid=\App\checkNull($this->skillid);
$p=\App\checkNull($this->p);
if($uid=='' || $token=='' || $sex<0 || $sex>2 || $age<0 || $age>5 ){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$type=0;
$domain = new Domain_User();
$list = $domain->getList($uid,$sex,$age,$skillid,$p,$type);
// $rs['info']=$list;
$rs['info'][0]['userlist']=$list;
//轮播图
/* 轮播 */
$domain_home = new Domain_Home();
$silidelist = $domain_home->getSilide();
$rs['info'][0]['silidelist']=$silidelist;
return $rs;
}
/**
* 关注列表
* @desc 用于获取用户关注列表
* @return int code 操作码0表示成功
* @return array info
* @return object info[] 用户基本信息
* @return string info[].isattent 是否关注0否1是
* @return string msg 提示信息
*/
public function getFollowlist() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$sex=\App\checkNull($this->sex);
$age=\App\checkNull($this->age);
$skillid=\App\checkNull($this->skillid);
$p=\App\checkNull($this->p);
if($uid=='' || $token=='' || $sex<0 || $sex>2 || $age<0 || $age>5 ){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$type=1;
$domain = new Domain_User();
$list = $domain->getList($uid,$sex,$age,$skillid,$p,$type);
$rs['info']=$list;
return $rs;
}
/**
* 最近三天认证用户列表
* @desc 用于获取 最近三天认证用户列表
* @return int code 操作码0表示成功
* @return array info
* @return object info[] 用户基本信息
* @return string info[].isattent 是否关注0否1是
* @return string msg 提示信息
*/
public function getAuthlistBF() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$sex=\App\checkNull($this->sex);
$age=\App\checkNull($this->age);
$skillid=\App\checkNull($this->skillid);
$p=\App\checkNull($this->p);
if($uid=='' || $token=='' || $sex<0 || $sex>2 || $age<0 || $age>5 ){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$type=2;
$domain = new Domain_User();
$list = $domain->getList($uid,$sex,$age,$skillid,$p,$type);
$rs['info']=$list;
return $rs;
}
/**
* 最近三天认证用户列表
* @desc 用于获取 最近三天认证用户列表
* @return int code 操作码0表示成功
* @return array info
* @return object info[] 用户基本信息
* @return string info[].isattent 是否关注0否1是
* @return string msg 提示信息
*/
public function getAuthlist() {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uid=\App\checkNull($this->uid);
$token=\App\checkNull($this->token);
$p=\App\checkNull($this->p);
if($uid=='' || $token==''){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$checkToken=\App\checkToken($uid,$token);
if($checkToken==700){
$rs['code'] = $checkToken;
$rs['msg'] = \PhalApi\T('您的登陆状态失效,请重新登陆!');
return $rs;
}
$type=2;
$domain = new Domain_User();
$res = $domain->getAuthlist($uid,$p,$type);
return $res;
}
}

View File

@ -0,0 +1,175 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\Cash as Model_Cash;
class Cash {
/* 我的:订单收益 */
public function getProfit($uid) {
$rs = array();
$model = new Model_Cash();
$info = $model->getProfit($uid);
$configpri=\App\getConfigPri();
//提现比例
$cash_rate=$configpri['cash_rate'];
$cash_start=$configpri['cash_start'];
$cash_end=$configpri['cash_end'];
$cash_max_times=$configpri['cash_max_times'];
//剩余票数
$votes=$info['votes'];
//总可提现数
$total=(string)floor($votes/$cash_rate);
//$tips='每月'.$cash_start.'-'.$cash_end.'号可进行提现申请,收益将在'.($cash_end+1).'-'.($cash_end+5).'号统一发放';
$tips=$configpri['cash_tip'];
$rs=array(
"votes"=>$votes,
"votestotal"=>$info['votestotal'],
"total"=>$total,
"cash_rate"=>$cash_rate,
"tips"=>$tips,
);
return $rs;
}
/* 提现:订单收益 */
public function setCash($data) {
$rs = array('code' => 0, 'msg' => \PhalApi\T('提现成功'), 'info' => array());
$nowtime=time();
$uid=$data['uid'];
$accountid=$data['accountid'];
$cashvote=$data['cashvote'];
$configpri=\App\getConfigPri();
$cash_start=$configpri['cash_start'];
$cash_end=$configpri['cash_end'];
$cash_max_times=$configpri['cash_max_times'];
$day=(int)date("d",$nowtime);
if($day < $cash_start || $day > $cash_end){
$rs['code'] = 1005;
$rs['msg'] = \PhalApi\T('不在提现期限内,不能提现');
return $rs;
}
//提现比例
$cash_rate=$configpri['cash_rate'];
/* 最低额度 */
$cash_min=$configpri['cash_min'];
//提现钱数
$money=floor($cashvote/$cash_rate);
if($money < $cash_min){
$rs['code'] = 1004;
$rs['msg'] = \PhalApi\T('提现最低额度为{n}元',['n'=>$cash_min]);
return $rs;
}
$model = new Model_Cash();
if($cash_max_times){
$nums=$model->getCashNums($uid);
if($nums >= $cash_max_times){
$rs['code'] = 1006;
$rs['msg'] = \PhalApi\T('每月只可提现{n}次,已达上限',['n'=>$cash_max_times]);
return $rs;
}
}
/* 钱包信息 */
$accountinfo=$model->getAccount($accountid);
if(!$accountinfo){
$rs['code'] = 1007;
$rs['msg'] = \PhalApi\T('提现账号信息不正确');
return $rs;
}
$cashvotes=$money*$cash_rate;
$ifok=$model->upVotes($uid,$cashvotes);
if(!$ifok){
$rs['code'] = 1001;
$rs['msg'] = \PhalApi\T('余额不足');
return $rs;
}
$data=array(
"uid"=>$uid,
"money"=>$money,
"votes"=>$cashvotes,
"votes_type"=>'0',//提现类型0订单收益提现1礼物收益提现
"orderno"=>$uid.'_'.date("ymdhis",$nowtime).rand(100,999),
"status"=>0,
"addtime"=>$nowtime,
"uptime"=>$nowtime,
"type"=>$accountinfo['type'],
"account_bank"=>$accountinfo['account_bank'],
"account"=>$accountinfo['account'],
"name"=>$accountinfo['name'],
);
$res = $model->setCash($data);
if(!$res){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('提现失败,请重试');
return $rs;
}
$votesinfo=$model->getVotes($uid);
$rs['info'][0]['votes']=$votesinfo['votes'];
return $rs;
}
/* 账号列表 */
public function getUserAccountList($uid) {
$rs = array();
$model = new Model_Cash();
$rs = $model->getUserAccountList($uid);
return $rs;
}
/* 设置账号 */
public function setUserAccount($data) {
$rs = array();
$model = new Model_Cash();
$rs = $model->setUserAccount($data);
return $rs;
}
/* 删除账号 */
public function delUserAccount($data) {
$rs = array();
$model = new Model_Cash();
$rs = $model->delUserAccount($data);
return $rs;
}
}

View File

@ -0,0 +1,64 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\Charge as Model_Charge;
class Charge {
/* 充值规则 */
public function getChargeRules() {
$key='getChargeRules';
$rules=\App\getcaches($key);
if(!$rules){
$model = new Model_Charge();
$rules= $model->getChargeRules();
if($rules){
\App\setcaches($key,$rules);
}
}
return $rules;
}
/* 生成订单 */
public function setOrder($changeid,$orderinfo) {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$model = new Model_Charge();
$charge = $model->getChargeRule($changeid);
if(!$charge){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
if($charge['money']!=$orderinfo['money'] || ($charge['coin']!=$orderinfo['coin'] && $charge['coin_ios']!=$orderinfo['coin'] && $charge['coin_paypal']!=$orderinfo['coin'])){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$orderinfo['coin_give']=$charge['give'];
$rs = $model->setOrder($orderinfo);
return $rs;
}
}

View File

@ -0,0 +1,228 @@
<?php
namespace App\Domain;
use App\Model\Comment as Model_Comment;
use App\Domain\Skill as Domain_Skill;
use App\Domain\Orders as Domain_Orders;
use App\Domain\User as Domain_User;
class Comment {
/* 评论主播 */
public function setComment($data) {
$rs = array('code' => 0, 'msg' => \PhalApi\T('评价成功'), 'info' => array());
$where=[
'orderid'=>$data['orderid'],
];
$model = new Model_Comment();
$isexist = $model->getCommentInfo($where);
if($isexist){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('您已经评价过了');
return $rs;
}
$where=[
'id'=>$data['orderid'],
'uid'=>$data['uid'],
];
$Domain_Orders = new Domain_Orders();
$orderinfo = $Domain_Orders->getOrderInfo($where);
if(!$orderinfo || $orderinfo['status']!=-2){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('订单无效,无法评价');
return $rs;
}
$data['liveuid']=$orderinfo['liveuid'];
$data['skillid']=$orderinfo['skillid'];
$Domain_Skill = new Domain_Skill();
if($data['label']!=''){
$label='';
$label_a=preg_split('/|,/',$data['label']);
$label_a=array_filter($label_a);
$nums=count($label_a);
if($nums>3){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('最多选择三个标签');
return $rs;
}
$list = $Domain_Skill->getLabel($data['skillid'],0);
foreach($label_a as $k=>$v){
foreach($list as $k1=>$v1){
if($v==$v1['id']){
$label.=$v1['id'].';';
$Domain_Skill->upLabelNums($data['liveuid'],$data['skillid'],$v1['id']);
}
}
}
$data['label']=$label;
}
$data['addtime']=time();
$res = $model->setComment($data);
if(!$res){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('评价失败,请重试');
return $rs;
}
/* 更新星级、评论数 */
$where=[
'uid'=>$data['liveuid'],
'skillid'=>$data['skillid'],
];
$Domain_Skill->upStar($where,$data['star'],1);
/* 更新用户星级、评论数 */
$Domain_User = new Domain_User();
$Domain_User->upStar($data['liveuid'],$data['star'],1);
/* 更新订单 */
$where2=[
'id'=>$data['orderid']
];
$data2=[
'iscommnet'=>'1'
];
$Domain_Orders->upOrder($where2,$data2);
return $rs;
}
/* 评价用户 */
public function setEvaluate($data) {
$rs = array('code' => 0, 'msg' => \PhalApi\T('评价成功'), 'info' => array());
$where=[
'orderid'=>$data['orderid'],
];
$model = new Model_Comment();
$isexist = $model->getEvaluateInfo($where);
if($isexist){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('您已经评价过了');
return $rs;
}
$where=[
'id'=>$data['orderid'],
'liveuid'=>$data['uid'],
];
$Domain_Orders = new Domain_Orders();
$orderinfo = $Domain_Orders->getOrderInfo($where);
if(!$orderinfo || $orderinfo['status']!=-2){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('订单无效,无法评价');
return $rs;
}
$data['touid']=$orderinfo['uid'];
$data['skillid']=$orderinfo['skillid'];
$data['addtime']=time();
$res = $model->setEvaluate($data);
if(!$res){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('评价失败,请重试');
return $rs;
}
/* 更新用户星级、评论数 */
$Domain_User = new Domain_User();
$Domain_User->upStar($data['touid'],$data['star'],1);
/* 更新订单 */
$where2=[
'id'=>$data['orderid']
];
$data2=[
'isevaluate'=>'1'
];
$Domain_Orders->upOrder($where2,$data2);
return $rs;
}
/* 技能评论总数 */
public function getCommentNums($where=''){
$model = new Model_Comment();
$nums=$model->getCommentNums($where);
return $nums;
}
/* 技能评论 */
public function getComment($p='1',$where='',$order='id desc'){
$model = new Model_Comment();
$Domain_Skill = new Domain_Skill();
$list=$model->getComment($p,$where,$order);
foreach($list as $k=>$v){
$userinfo=\App\getUserInfo($v['uid']);
unset($userinfo['birthday']);
$v['userinfo']=$userinfo;
$v['add_time']=\App\offtime($v['addtime']);
$label=[];
$label_a=preg_split('/;|/',$v['label']);
$label_a=array_filter($label_a);
$labellist=$Domain_Skill->getLabel($v['skillid']);
foreach($label_a as $k1=>$v1){
foreach($labellist as $k2=>$v2){
if($v1==$v2['id']){
$label[]=$v2['name'];
}
}
}
$v['label_a']=$label;
unset($v['label']);
$list[$k]=$v;
}
return $list;
}
/* 用户评论 */
public function getEvaluate($where=''){
$model = new Model_Comment();
$info=$model->getEvaluateInfo($where);
if($info){
$userinfo=\App\getUserInfo($info['touid']);
unset($userinfo['birthday']);
$info['userinfo']=$userinfo;
}
return $info;
}
}

View File

@ -0,0 +1,27 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\Guide as Model_Guide;
class Guide {
public function getGuide() {
$rs = array();
$model = new Model_Guide();
$rs = $model->getGuide();
return $rs;
}
}

View File

@ -0,0 +1,94 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\Home as Model_Home;
use App\Domain\Skill as Domain_Skill;
class Home {
/* 广告 */
public function getSilide($id='1') {
$key='getSilide_'.$id;
$list=\App\getcaches($key);
if(!$list){
$model = new Model_Home();
$list= $model->getSilide($id);
if($list){
\App\setcaches($key,$list);
}
}
foreach($list as $k=>$v){
$v['image']=\App\get_upload_path($v['image']);
$list[$k]=$v;
}
return $list;
}
/* 用户列表 */
public function getUsers($uid='0',$p='1') {
$model = new Model_Home();
$list= $model->getUsers($uid,$p);
$Domain_skill=new Domain_Skill();
$order='orders desc';
foreach($list as $k=>$v){
$v=\App\handleUser($v);
$where=[];
$where['uid']=$v['id'];
$where['switch']='1';
$where['status']='1';
$skills=$Domain_skill->getSkillAuth($where,$order);
$skills=array_slice($skills,0,3);
$list2=[];
foreach($skills as $k1=>$v1){
$info=$Domain_skill->getSkill($v1['skillid']);
$list2[]=[
'name'=>$info['name'],
'colour_font'=>$info['colour_font'],
'colour_bg'=>$info['colour_bg'],
];
}
$v['list']=$list2;
unset($v['birthday']);
$list[$k]=$v;
}
return $list;
}
/* 搜索用户 */
public function searchUser($keyword,$p='1') {
$model = new Model_Home();
$list= $model->searchUser($keyword,$p);
foreach($list as $k=>$v){
$v=\App\handleUser($v);
unset($v['birthday']);
$list[$k]=$v;
}
return $list;
}
}

View File

@ -0,0 +1,35 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\Im as Model_Im;
class Im {
/* 系统通知 */
public function getSysNotice($uid,$p) {
$model = new Model_Im();
$list= $model->getSysNotice($uid,$p);
foreach($list as $k=>$v){
unset($v['ip']);
$v['addtime']=date("Y-m-d H:i:s",$v['addtime']);
$list[$k]=$v;
}
return $list;
}
}

View File

@ -0,0 +1,112 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\Login as Model_Login;
class Login {
public function userLogin($user_login,$source) {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$where=[
'user_login = ?'=>$user_login,
];
$model = new Model_Login();
$info = $model->userLogin($where);
if(!$info){
/* 注册 */
$nickname='';
$data=array(
'user_login' => $user_login,
'user_nickname' => $nickname,
"source"=>$source,
"mobile"=>$user_login,
);
$model = new Model_Login();
$info = $model->userReg($data);
}
$info=$this->handleInfo($info);
return $info;
}
public function reg($user_login,$user_pass,$source) {
$rs = array('code' => 0, 'msg' => \PhalApi\T('注册成功'), 'info' => array());
/* 注册 */
$data=array(
'user_login' => $user_login,
'user_pass' => $user_pass,
'user_nickname' => $nickname,
"source"=>$source,
"user_email"=>$user_login,
);
$model = new Model_Login();
$info = $model->userReg($data);
$info=$this->handleInfo($info);
return $info;
}
protected function handleInfo($info){
$rs = array('code' => 0, 'msg' => \PhalApi\T('登录成功'), 'info' => array());
if($info['user_status']=='0'){
$rs['code'] = 1004;
$rs['msg'] = \PhalApi\T('该账号已被禁用');
return $rs;
}
if($info['user_status']=='3'){
$rs['code'] = 1005;
$rs['msg'] = \PhalApi\T('该账号已注销');
return $rs;
}
unset($info['user_status']);
$info['isreg']='0';
if(!$info['last_login_time']){
$info['isreg']='1';
}
unset($info['last_login_time']);
$info=\App\handleUser($info);
\App\delcache('userinfo_'.$info['id']);
$model = new Model_Login();
$token=md5(md5($info['id'].$info['user_nickname'].time()));
$info['token']=$token;
$model->updateToken($info['id'],$token);
$usersig=\App\setSig($info['id']);
$info['usersig']=$usersig;
$rs['info'][0]=$info;
return $rs;
}
}

View File

@ -0,0 +1,935 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\Orders as Model_Orders;
use App\Domain\Skill as Domain_Skill;
use App\Domain\Comment as Domain_Comment;
class Orders {
public function handelInfo($uid,$info){
$overtime=$info['overtime'];
$nowtime=time();
$info['ishideok']="0";
if($overtime>$nowtime){
$info['ishideok']="1";
}
$info['svctm']=\App\handelsvctm($info['svctm']);
/* 费用 */
$info['fee']= $info['fee']==0? '0':'-'.$info['fee'];
if($info['status']=='1'){
//订单超时剩余时间
$remainingtime=$info['addtime']+15*60-$nowtime;
$info['remainingtime']=$remainingtime;
}else{
$info['remainingtime']=0;
}
if($uid==$info['uid']){
$userinfo=\App\getUserInfo($info['liveuid']);
}else{
$userinfo=\App\getUserInfo($info['uid']);
}
unset($userinfo['birthday']);
$info['userinfo']=$userinfo;
/* 技能 */
$Domain_Skill = new Domain_Skill();
$skillinfo=$Domain_Skill->getSkill($info['skillid']);
$skill=[
'id'=>isset($skillinfo['id']) ? $skillinfo['id'] : '0',
'name'=>isset($skillinfo['name']) ? $skillinfo['name'] : \PhalApi\T('已移除'),
'method'=>isset($skillinfo['method']) ? $skillinfo['method'] : '',
'thumb'=>isset($skillinfo['thumb']) ? $skillinfo['thumb'] : '',
];
$info['skill']=$skill;
/* 技能配置 */
$auth=[
'switch'=>'0',
'coin'=>'0',
];
$where=[
'uid'=>$info['liveuid'],
'skillid'=>$info['skillid'],
'status'=>'1',
'switch'=>'1',
];
$authlist= $Domain_Skill->getSkillAuth($where);
if($authlist){
$auth['switch']='1';
$auth['coin']=$authlist[0]['coin'];
}
$info['auth']=$auth;
$info['skill']['coin']=$auth['coin'];
$iscommnet='0';//技能评论:下单人对接单人的技能评论
$comment=(object)[];
if($info['status']==-2){
$Domain_Comment=new Domain_Comment();
$where=[
'orderid'=>$info['id']
];
$commentinfo=$Domain_Comment->getComment(1,$where);
if($commentinfo){
$iscommnet='1';
$comment=$commentinfo[0];
}
}
$info['iscommnet']=$iscommnet;
$info['comment']=$comment;
/* 主播给用户评价 */
$isevaluate='0';
$evaluate=(object)[];
if($info['status']==-2){
$Domain_Comment=new Domain_Comment();
$where=[
'orderid'=>$info['id']
];
$evaluateinfo=$Domain_Comment->getEvaluate($where);
if($evaluateinfo){
$isevaluate='1';
$evaluate=$evaluateinfo;
}
}
$info['isevaluate']=$isevaluate;
$info['evaluate']=$evaluate;
unset($info['type']);
unset($info['ambient']);
unset($info['paytime']);
unset($info['receipttime']);
unset($info['oktime']);
unset($info['canceltime']);
// unset($info['orderno']);
unset($info['trade_no']);
return $info;
}
/* 进行订单 */
public function getOrdersing($uid) {
$where["(uid=? or liveuid=?) and status in(1,2,3,4,6)"]=[$uid,$uid];//不显示未支付的信息0
$model = new Model_Orders();
$list= $model->getOrdersing($where);
foreach($list as $k=>$v){
$v=$this->handelInfo($uid,$v);
$list[$k]=$v;
}
return $list;
}
/* 订单 */
public function getOrders($uid,$p) {
/* $where=[
'status < ?'=>'0'
];
$where['uid=? or liveuid=?']=[$uid,$uid]; */
$where["(uid=? or liveuid=?) and status in(-4,-3,-2,-1,5)"]=[$uid,$uid];
$model = new Model_Orders();
$list= $model->getOrders($p,$where);
foreach($list as $k=>$v){
$v=$this->handelInfo($uid,$v);
$list[$k]=$v;
}
return $list;
}
/* 订单状态 */
public function checkOrder($data){
$model = new Model_Orders();
$info = $model->getOrderInfo($data);
return $info;
}
/* 生成订单 */
public function checkset($data) {
$rs = array('code' => 0, 'msg' => \PhalApi\T('下单成功'), 'info' => array());
$uid=$data['uid'];
$liveuid=$data['liveuid'];
$type=$data['type'];
$svctm=$data['svctm'];
$paytype=$data['paytype'];
$des=$data['des'];
unset($data['svctm']);
unset($data['type']);
unset($data['paytype']);
$data['type']=$paytype;
if($uid==$liveuid){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('不能给自己下单');
return $rs;
}
$svctminfo=\App\treatsvctm($type,$svctm);
if($svctminfo['code']!=0){
return $svctminfo;
}
$data['svctm']=$svctminfo['info']['svctm'];
$nowtime=time();
if(mb_strlen($des) > 50){
$rs['code']=1005;
$rs['msg']=\PhalApi\T('备注不能超过50字');
return $rs;
}
$data['order_type']='0';
$res=$this->setOrder($data);
return $res;
}
/* 下单-支付 */
public function setOrder($data){
$rs = array('code' => 0, 'msg' =>"", 'info' => array());
$uid=$data['uid'];
$liveuid=$data['liveuid'];
$skillid=$data['skillid'];
$nums=$data['nums'];
$Domain_Skill=new Domain_Skill();
$where=[
'uid'=>$liveuid,
'skillid'=>$skillid,
'status'=>'1',
'switch'=>'1',
];
$order='id desc';
$auth=$Domain_Skill->getSkillAuth($where,$order);
if(!$auth){
$rs['code']=1006;
$rs['msg']=\PhalApi\T('该技能对方未认证或未开启');
return $rs;
}
$authinfo=$auth[0];
$total=$authinfo['coin'] * $nums;
if($total<=0){
$rs['code']=1007;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$coinid=$authinfo['coinid'];
$coininfo=$Domain_Skill->getCoin($coinid);
$fee_base=isset($coininfo['fee']) ? $coininfo['fee'] : '0';
$fee=$fee_base * $nums;
$data['total']=$total;
$data['fee']=$fee;
$data['profit']=$total - $fee;
$nowtime=time();
$orderno=$uid.'_'.date('ymdHis').rand(100,999)."_"."2";//1充值2订单
$data['orderno']=$orderno;
$data['addtime']=$nowtime;
$skillinfo=$Domain_Skill->getSkill($skillid);
$overtime=$data['svctm']+$skillinfo['methodminutes']*60* $nums;
$data['overtime']=$overtime;//订单陪玩结束时间
$paytype=$data['type'];
if($paytype==0){
/* 余额支付 */
$res=\App\upCoin($uid,$total);
if(!$res){
$rs['code']=1008;
$rs['msg']=\PhalApi\T('余额不足');
return $rs;
}
$data['status']='1';
if($data['order_type']==1){
$data['status']='2';
}
$data['paytime']=$nowtime;
}
$model = new Model_Orders();
$res = $model->setOrder($data);
$configpri = \App\getConfigPri();
if($paytype==0){
$record=[
'type'=>'0',
'action'=>'1',
'uid'=>$uid,
'touid'=>$liveuid,
'actionid'=>$res['id'],
'nums'=>$nums,
'total'=>$total,
'addtime'=>$nowtime,
];
\App\addCoinRecord($record);
/* 余额支付 下单即支付 立即发送IM*/
$imdata=$this->handelInfo($liveuid,$res);
$userinfo=\App\getUserInfo($uid);
$imdata['tips']=$userinfo['user_nickname'].'给你下了订单';
//$imdata['tips_en']=$userinfo['user_nickname'].' placed an order for you';
$this->sendImOrder($liveuid,$imdata);
if($data['order_type']!=1){
$msg=\PhalApi\T('订单已收到,会尽快确认');
// $this->sendIm($liveuid,$uid,$msg);
}
}
$info['orderno']=$orderno;
$info['orderid']=$res['id'];
$info['total']=(string)$total;
$rs['info'][0]=$info;
return $rs;
}
/**
* sign拼装获取
*/
protected function sign($param,$key){
$sign = "";
foreach($param as $k => $v){
$sign .= $k."=".$v."&";
}
$sign .= "key=".$key;
$sign = strtoupper(md5($sign));
return $sign;
}
/* 获取取消原因 */
public function getCancelList(){
$key='getCancelList';
$list=\App\getcaches($key);
if(!$list){
$model = new Model_Orders();
$list=$model->getCancelList();
if($list){
\App\setcaches($key,$list);
}
}
foreach($list as $k=>$v){
if(\PhalApi\DI()->lang=='en' && $v['name_en']!=''){
$v['name']=$v['name_en'];
}
unset($v['name_en']);
$list[$k]=$v;
}
return $list;
}
/* 取消订单 */
public function cancelOrder($uid,$orderid,$reasonid){
$rs = array('code' => 0, 'msg' => \PhalApi\T('操作成功'), 'info' => array());
$where=[
'id'=>$orderid
];
$model = new Model_Orders();
$info = $model->getOrderInfo($where);
if(!$info){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
if($info['uid']!=$uid){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$nowtime=time();
$status=$info['status'];
if($status!=1 && $status!=0 ){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('该订单不能取消');
return $rs;
}
$reason='';
/* 原因处理 */
if($reasonid!=''){
$reasonid_a=preg_split('/|,/',$reasonid);
$reasonid_a=array_filter($reasonid_a);
$list = $this->getCancelList();
foreach($reasonid_a as $k=>$v){
foreach($list as $k1=>$v1){
if($v==$v1['id']){
$reason.=$v1['name'].';';
}
}
}
}
if($reason==''){
$rs['code']=1005;
$rs['msg']=\PhalApi\T('请选择原因');
return $rs;
}
$tips='订单:您取消了一个订单';
$tips_en='Order: you canceled an order';
if($status==1){
/* 已付款 退回 */
$total=$info['total'];
$res=\App\addCoin($uid,$total);
$record=[
'type'=>'1',
'action'=>'2',
'uid'=>$uid,
'touid'=>$info['liveuid'],
'actionid'=>$info['id'],
'nums'=>$info['nums'],
'total'=>$total,
'addtime'=>$nowtime,
];
\App\addCoinRecord($record);
$tips='订单:您取消了一个订单,费用'.$total.'已退回';
$tips_en='Order: you canceled an order and the fee '.$total.' has been returned';
}
/* 更新订单 */
$data=[
'status'=>-1,
'canceltime'=>$nowtime,
'reason'=>$reason,
];
$where=[
'id'=>$info['id'],
];
$res = $model->upOrder($where,$data);
/* 发送IM*/
/* 发给自己 */
$info['status']='-1';
$imdata=$this->handelInfo($uid,$info);
$imdata['tips']=$tips;
$imdata['tips_en']=$tips_en;
$this->sendImOrder($uid,$imdata);
/* 发给对方 */
$imdata2=$this->handelInfo($info['liveuid'],$info);
$imdata2['tips']='订单:很抱歉,用户取消了您的订单哦~';
$imdata2['tips_en']='Order: sorry, the user canceled your order~';
$this->sendImOrder($info['liveuid'],$imdata2);
return $rs;
}
/* 获取订单详情 */
public function getOrderDetail($uid,$orderid){
$where=[
'id=?'=>$orderid,
'uid=? or liveuid=?'=>[$uid,$uid]
];
$model = new Model_Orders();
$info = $model->getOrderInfo($where);
if($info){
$info=$this->handelInfo($uid,$info);
}
return $info;
}
/* 获取服务状态的订单详情 */
public function getReceptOrderDetail($uid,$orderid){
$where=[
'id=?'=>$orderid,
'uid=? or liveuid=?'=>[$uid,$uid]
];
$model = new Model_Orders();
$info = $model->getSomeOrderInfo($where);
if($info){
$info['svctm']=\App\handelsvctm($info['svctm']);
}
return $info;
}
/* 获取订单信息 */
public function getOrderInfo($where){
$model = new Model_Orders();
$info = $model->getOrderInfo($where);
return $info;
}
/* 接单 */
public function receiptOrder($uid,$orderid){
$rs = array('code' => 0, 'msg' => \PhalApi\T('操作成功'), 'info' => array());
$where=[
'id'=>$orderid
];
$model = new Model_Orders();
$info = $model->getOrderInfo($where);
if(!$info){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
if($info['liveuid']!=$uid){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$nowtime=time();
$status=$info['status'];
if($status!=1 ){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('该订单未付款,无法接单');
return $rs;
}
/* 更新订单 */
$data=[
'status'=>2,
'receipttime'=>$nowtime,
];
$where=[
'id'=>$info['id'],
];
$res = $model->upOrder($where,$data);
/* 发送IM*/
$info['status']='2';
$tips='大神通过了您的订单,快去让大神带起飞吧';
$imdata=$this->handelInfo($info['uid'],$info);
$imdata['tips']=$tips;
$this->sendImOrder($info['uid'],$imdata);
return $rs;
}
/* 拒单 */
public function refuseOrder($uid,$orderid){
$rs = array('code' => 0, 'msg' => \PhalApi\T('操作成功'), 'info' => array());
$where=[
'id'=>$orderid
];
$model = new Model_Orders();
$info = $model->getOrderInfo($where);
if(!$info){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
if($info['liveuid']!=$uid){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$nowtime=time();
$status=$info['status'];
if($status!=1){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('订单已处理,无法操作');
return $rs;
}
$tips='订单:很抱歉,大神没通过订单哦';
$tips_en="Order: I'm sorry, the master didn't pass the order";
if($status==1){
/* 已付款 拒绝-退回 */
$total=$info['total'];
$res=\App\addCoin($info['uid'],$total);
$record=[
'type'=>'1',
'action'=>'2',
'uid'=>$info['uid'],
'touid'=>$info['liveuid'],
'actionid'=>$info['id'],
'nums'=>$info['nums'],
'total'=>$total,
'addtime'=>$nowtime,
];
\App\addCoinRecord($record);
$recordv=[
'type'=>'0',
'action'=>'2',
'uid'=>$info['uid'],
'fromid'=>$info['liveuid'],
'actionid'=>$info['id'],
'nums'=>$info['nums'],
'total'=>$total,
'addtime'=>$nowtime,
];
\App\addVotesRecord($recordv);
$tips='订单:很抱歉,大神没通过订单哦,费用'.$total.'已退回';
$tips_en="Order: I'm sorry, great god didn't pass the order. the fee {$total} has been returned";
}
/* 更新订单 */
$data=[
'status'=>-3,
'receipttime'=>$nowtime,
];
$where=[
'id'=>$info['id'],
];
$res = $model->upOrder($where,$data);
/* 发送IM*/
$info['status']='-3';
$imdata=$this->handelInfo($info['uid'],$info);
$imdata['tips']=$tips;
$imdata['tips_en']=$tips_en;
$this->sendImOrder($info['uid'],$imdata);
return $rs;
}
/* 完成订单 */
public function completeOrder($uid,$orderid){
$rs = array('code' => 0, 'msg' => \PhalApi\T('操作成功'), 'info' => array());
$where=[
'id'=>$orderid
];
$model = new Model_Orders();
$info = $model->getOrderInfo($where);
if(!$info){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
if($info['uid']!=$uid){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$nowtime=time();
$status=$info['status'];
if($status !=2 ){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('对方还未接单,无法完成');
return $rs;
}
/* 主播收益 */
$profit=$info['profit'];
$res=\App\addVotes($info['liveuid'],$profit,$profit);
$record=[
'type'=>'0',
'action'=>'1',
'uid'=>$info['liveuid'],
'fromid'=>$uid,
'actionid'=>$info['id'],
'nums'=>$info['nums'],
'total'=>$profit,
'addtime'=>$nowtime,
];
\App\addVotesRecord($record);
/* 更新订单 */
$data=[
'status'=>-2,
'oktime'=>$nowtime,
];
$where=[
'id'=>$info['id'],
];
$res = $model->upOrder($where,$data);
/* 更新接单数 */
$where=[
'uid'=>$info['liveuid'],
'skillid'=>$info['skillid'],
];
$Domain_Skill = new Domain_Skill();
$skilllist= $Domain_Skill->upOrsers($where,1);
/* 分销--消费分成停用setAgentProfit ,改为充值分成*/
//\App\setAgentProfit($uid,$info['total']);
/* 发送IM*/
$info['status']='-2';
$tips='接单:订单已经结束了,收入'.$profit;
$tips_en='Receipt: the order has been completed and the income is '.$profit.'. You can give make a comment on the user';
$imdata=$this->handelInfo($info['liveuid'],$info);
$imdata['tips']=$tips;
$imdata['tips_en']=$tips_en;
$this->sendImOrder($info['liveuid'],$imdata);
return $rs;
}
/* 更新订单 */
public function upOrder($where,$data) {
$model = new Model_Orders();
$order= $model->upOrder($where,$data);
return $info;
}
/* 获取用户间进行中的订单 */
public function getOrdering($uid,$touid) {
$where=[
'(uid=? and liveuid=? and (`status`=2 or `status`=1 ) ) or (uid=? and liveuid=? and (`status`=2 or `status`=1 ) ) or (uid=? and liveuid=? and `status`=-2 and iscommnet=0) or (uid=? and liveuid=? and `status`=-2 and isevaluate=0) ' =>[$uid,$touid,$touid,$uid,$uid,$touid,$touid,$uid],
];
$info=[
'isexist'=>'0',
'order'=>(object)[],
];
$model = new Model_Orders();
$order= $model->getOrderInfo($where);
if($order){
$order=$this->handelInfo($uid,$order);
$info['isexist']='1';
$info['order']=$order;
}
return $info;
}
/* 发送订单消息 */
protected function sendImOrder($touid,$data){
$data['method']='orders';
$ext=$data;
#构造高级接口所需参数
$msg_content = array();
//创建array 所需元素
$msg_content_elem = array(
'MsgType' => 'TIMCustomElem', //自定义类型
'MsgContent' => array(
'Data' => json_encode($ext),
'Desc' => '',
// 'Ext' => $ext,
// 'Sound' => '',
)
);
//将创建的元素$msg_content_elem, 加入array $msg_content
array_push($msg_content, $msg_content_elem);
$account_id=(string)0;
$receiver=(string)$touid;
$api=\App\getTxRestApi();
$ret = $api->openim_send_msg_custom($account_id, $receiver, $msg_content,2);
file_put_contents(API_ROOT.'/runtime/sendImOrder'.date('Y-m-d').'.txt',date('y-m-d H:i:s').'提交参数信息 ext:'.json_encode($ext)."\r\n",FILE_APPEND);
file_put_contents(API_ROOT.'/runtime/sendImOrder'.date('Y-m-d').'.txt',date('y-m-d H:i:s').'提交参数信息 ret:'.json_encode($ret)."\r\n",FILE_APPEND);
/* IM */
return 1;
}
/* 发送私信消息 */
protected function sendIm($uid,$touid,$msg){
/* IM */
#构造高级接口所需参数
$msg_content = array();
//创建array 所需元素
$msg_content_elem = array(
'MsgType' => 'TIMTextElem', //文本消息
'MsgContent' => array(
"Text"=>$msg
)
);
//将创建的元素$msg_content_elem, 加入array $msg_content
array_push($msg_content, $msg_content_elem);
$account_id=(string)$uid;
$receiver=(string)$touid;
$api=\App\getTxRestApi();
$ret = $api->openim_send_msg_custom($account_id, $receiver, $msg_content,2);
file_put_contents(API_ROOT.'/runtime/sendIm'.date('Y-m-d').'.txt',date('y-m-d H:i:s').'提交参数信息 uid:'.json_encode($uid)."\r\n",FILE_APPEND);
file_put_contents(API_ROOT.'/runtime/sendIm'.date('Y-m-d').'.txt',date('y-m-d H:i:s').'提交参数信息 touid:'.json_encode($touid)."\r\n",FILE_APPEND);
file_put_contents(API_ROOT.'/runtime/sendIm'.date('Y-m-d').'.txt',date('y-m-d H:i:s').'提交参数信息 ret:'.json_encode($ret)."\r\n",FILE_APPEND);
/* IM */
return 1;
}
/* 接单后:接单者:更新服务状态 */
public function upReceptStatus($uid,$orderid,$recept_status){
$rs = array('code' => 0, 'msg' => \PhalApi\T('已拒绝'), 'info' => array());
$where=[
'id'=>$orderid
];
$model = new Model_Orders();
$info = $model->getOrderInfo($where);
if(!$info){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('信息错误');
return $rs;
}
$nowtime=time();
$status=$info['status'];
if($status!=2 ){
$rs['code']=1004;
$rs['msg']=\PhalApi\T('该订单未接单或已完成,无法发起服务申请');
return $rs;
}
/* 更新订单 */
$data=[
'recept_status'=>$recept_status,
];
if($recept_status=='2'){//同意立即服务
$Domain_Skill = new Domain_Skill();
$skillinfo=$Domain_Skill->getSkill($info['skillid']);
$data['svctm']=$nowtime;
$data['overtime']=$nowtime+$skillinfo['methodminutes']*60*$info['nums'];
}
$where=[
'id'=>$info['id'],
];
$res = $model->upOrder($where,$data);
/* 发送IM*/
$info['method']="upreceptstatus";
$info['action']=$recept_status;
$info['recept_status']=$recept_status;
$info['svctm']=\App\handelsvctm($info['svctm']);
unset($info['type']);
unset($info['ambient']);
unset($info['paytime']);
unset($info['receipttime']);
unset($info['oktime']);
unset($info['canceltime']);
unset($info['orderno']);
unset($info['trade_no']);
//\App\sendImSysCustom($uid,$info,3);
// \App\sendImSysCustom($info['liveuid'],$info,3);
// file_put_contents(API_ROOT.'/runtime/aaupReceptStatus'.date('Y-m-d').'.txt',date('y-m-d H:i:s').'提交参数信息 info:'.json_encode($info)."\r\n",FILE_APPEND);
if($recept_status=='2'){
$rs['msg']=\PhalApi\T('已同意');
$ext=['action'=>'2','method'=>'orderstart','uid'=>$uid,'liveuid'=>$info['liveuid'],'tip_title'=>'订单开始','tip_des'=>'订单已开始,愿本次体验愉快','tip_des2'=>'对方已同意立即服务,订单已开始,愿本次体验愉快'];
/* file_put_contents(API_ROOT.'/runtime/aaupReceptStatus'.date('Y-m-d').'.txt',date('y-m-d H:i:s').'提交参数信息 recept_status:'.json_encode($recept_status)."\r\n",FILE_APPEND);
file_put_contents(API_ROOT.'/runtime/aaupReceptStatus'.date('Y-m-d').'.txt',date('y-m-d H:i:s').'提交参数信息 ext:'.json_encode($ext)."\r\n",FILE_APPEND); */
//\App\sendImCustom($uid,$info['liveuid'],$ext,0,1);//下单用户同意后下单方发送订单开始IM
}
return $rs;
}
}

View File

@ -0,0 +1,827 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\Skill as Model_Skill;
use App\Domain\Comment as Domain_Comment;
class Skill {
/* 分类 */
public function getClass() {
$key='getSkillclass';
$list=\App\getcaches($key);
if(!$list){
$model = new Model_Skill();
$list=$model->getClass();
if($list){
\App\setcaches($key,$list);
}
}
foreach($list as $k=>$v){
if(\PhalApi\DI()->lang=='en' && $v['name_en']!=''){
$v['name']=$v['name_en'];
}
unset($v['name_en']);
$list[$k]=$v;
}
return $list;
}
/* 技能列表 */
public function getSkillList() {
$key='getSkilllist';
$list=\App\getcaches($key);
if(!$list){
$model = new Model_Skill();
$list=$model->getSkillList();
if($list){
\App\setcaches($key,$list);
}
}
foreach($list as $k=>$v){
$v['thumb']=\App\get_upload_path($v['thumb']);
if(\PhalApi\DI()->lang=='en' && $v['name_en']!=''){
$v['name']=$v['name_en'];
}
unset($v['name_en']);
$v['method']=\PhalApi\T($v['method']);
unset($v['auth_tip']);
unset($v['auth_tip_en']);
unset($v['list_order']);
$list[$k]=$v;
}
return $list;
}
/* 全部分类 */
public function getAll(){
$class = $this->getClass();
$skilllist = $this->getSkillList();
foreach($class as $k=>$v){
$list=[];
foreach($skilllist as $k1=>$v1){
if($v['id']==$v1['classid']){
unset($v1['list_order']);
unset($v1['colour_font']);
unset($v1['colour_bg']);
unset($v1['classid']);
$list[]=$v1;
}
}
$v['list']=$list;
$class[$k]=$v;
}
return $class;
}
/* 选择技能认证 */
public function getUserSkill($uid){
$class = $this->getClass();
$skilllist = $this->getSkillList();
$where=[];
$where['uid']=$uid;
$order='id desc';
$model = new Model_Skill();
$authlist=$model->getSkillAuth($where,$order);
foreach($class as $k=>$v){
$list=[];
foreach($skilllist as $k1=>$v1){
if($v['id']==$v1['classid']){
$status='-1';
foreach($authlist as $k2=>$v2){
if($v2['skillid']==$v1['id']){
$status=$v2['status'];
}
}
$v1['status']=$status;
unset($v1['list_order']);
unset($v1['colour_font']);
unset($v1['colour_bg']);
unset($v1['classid']);
$list[]=$v1;
}
}
$v['list']=$list;
$class[$k]=$v;
}
return $class;
}
/* 我的技能 */
public function getMySkill($uid){
$skilllist = $this->getSkillList();
$where=[];
$where['uid']=$uid;
$where['status']=1;
$order='id desc';
$list=$this->getSkillAuth($where,$order);
foreach($list as $k=>$v){
foreach($skilllist as $k1=>$v1){
if($v['skillid']==$v1['id']){
unset($v1['list_order']);
unset($v1['colour_font']);
unset($v1['colour_bg']);
$skill=$v1;
}
}
$v['skill']=$skill;
$list[$k]=$v;
}
return $list;
}
/* 价格列表 */
public function getCoinList(){
$key='skill_coinlist';
$list=\App\getcaches($key);
if(!$list){
$model = new Model_Skill();
$list=$model->getCoinList();
if($list){
\App\setcaches($key,$list);
}
}
return $list;
}
/* 某价格信息 */
public function getCoin($id){
$info=[];
$list=$this->getCoinList();
foreach($list as $k=>$v){
if($v['id']==$id){
$info=$v;
break;
}
}
return $info;
}
/* 可选价格 */
public function getCoins($uid,$skillid){
$list=$this->getCoinList();
$where=[];
$where['uid']=$uid;
$where['skillid']=$skillid;
$order='id desc';
$orders='0';
$model = new Model_Skill();
$authlist=$model->getSkillAuth($where,$order);
if($authlist){
$orders=$authlist[0]['orders'];
}
foreach($list as $k=>$v){
$canselect='0';
if($v['orders']<=$orders){
$canselect='1';
}
$v['canselect']=$canselect;
$list[$k]=$v;
}
return $list;
}
/* 更新技能开关 */
public function setSwitch($uid,$skillid,$data){
$rs = array('code' => 0, 'msg' => \PhalApi\T('操作成功'), 'info' => array());
$where=[];
$where['uid']=$uid;
$where['skillid']=$skillid;
$order='id desc';
$model = new Model_Skill();
$authlist=$model->getSkillAuth($where,$order);
if(!$authlist){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$auth=$authlist[0];
if($auth['status']!=1){
$rs['code'] = 1003;
$rs['msg'] = \PhalApi\T('请等待技能认证通过');
return $rs;
}
if($auth['coin']==0){
$rs['code'] = 1004;
$rs['msg'] = \PhalApi\T('请先设置价格');
return $rs;
}
$authlist=$model->upSkill($where,$data);
$this->upUserSwitch($uid,$data['switch']);
return $rs;
}
/* 更新用户表状态 */
public function upUserSwitch($uid,$isswitch){
$model = new Model_Skill();
if($isswitch==0){
$where=[];
$where['uid']=$uid;
$where['switch']=1;
$order='id desc';
$list=$model->getSkillAuth($where,$order);
if($list){
$isswitch=1;
}
}
$res=$model->upUserSwitch($uid,$isswitch);
return $res;
}
/* 更新技能信息 */
public function upSkill($uid,$skillid,$fields){
$rs = array('code' => 0, 'msg' => \PhalApi\T('操作成功'), 'info' => array());
$data=[];
$info=[];
/* 价格 */
if( isset($fields['coin']) && $fields['coin']!='' ){
$coinid=$fields['coin'];
$where=[];
$where['uid']=$uid;
$where['skillid']=$skillid;
$order='id desc';
$orders='0';
$model = new Model_Skill();
$authlist=$model->getSkillAuth($where,$order);
if($authlist){
$orders=$authlist[0]['orders'];
}
$coin='0';
$list=$this->getCoinList();
foreach($list as $k=>$v){
if($v['id']==$coinid && $v['orders']<=$orders){
$coin=$v['coin'];
break;
}
}
if(!$coin){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('请选择正确的价格');
return $rs;
}
if($coin){
$data['coinid']=$coinid;
$data['coin']=$coin;
$info['coin']=$coin;
}
}
/* 标签 */
if( isset($fields['label']) && $fields['label']!='' ){
$label='';
$label_a2=[];
$label_a=preg_split('/,|/',$fields['label']);
$label_a=array_filter($label_a);
$nums=count($label_a);
if($nums>3){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('最多选择三个标签');
return $rs;
}
$list = $this->getLabel($skillid);
foreach($label_a as $k=>$v){
foreach($list as $k1=>$v1){
if($v==$v1['id']){
$label.=$v1['id'].';';
$label_a2[]=$v1['name'];
}
}
}
if($label){
$data['label']=$label;
$info['label_a']=$label_a2;
}
}
/* 段位 */
if( isset($fields['level']) && $fields['level']!='' ){
$levelid2=$fields['level'];
$levelinfo=$this->getLevelInfo($skillid,$levelid2);
$level=isset($levelinfo['name']) ? $levelinfo['name'] : '';
$levelid=isset($levelinfo['levelid']) ? $levelinfo['levelid'] : '0';
if($levelid){
$data['levelid']=$levelid;
$info['levelid']=$levelid;
$info['level']=$level;
}
}
/* 截图 */
if( isset($fields['thumb']) && $fields['thumb']!='' ){
$thumb=$fields['thumb'];
$thumb_path=\App\set_upload_path($thumb);
$data['thumb']=$thumb_path;
$info['thumb']=\App\get_upload_path($thumb_path);
}
/* 语音 */
if( isset($fields['voice']) && $fields['voice']!='' ){
$voice=$fields['voice'];
$voice_l=$fields['voice_l'];
$voice_path=\App\set_upload_path($voice);
$data['voice']=$voice_path;
$data['voice_l']=$voice_l;
$info['voice']=\App\get_upload_path($voice_path);
$info['voice_l']=$voice_l;
}
/* 介绍 */
if( isset($fields['des']) && $fields['des']!='' ){
$des=$fields['des'];
if(mb_strlen($des)>30){
$rs['code']=1003;
$rs['msg']=\PhalApi\T('介绍最多30个字');
return $rs;
}
$data['des']=$des;
$info['des']=$des;
}
if(!$data){
return $rs;
}
$where=[];
$where['uid']=$uid;
$where['skillid']=$skillid;
$where['status']='1';
$model = new Model_Skill();
$authlist=$model->upSkill($where,$data);
$rs['info'][0]=$info;
return $rs;
}
/* 更新星级、评论 */
public function upStar($where,$star=1,$comments=1) {
if(!$where){
return 0;
}
$model = new Model_Skill();
$list=$model->upStar($where,$star,$comments);
return $rs;
}
/* 更新订单数 */
public function upOrsers($where,$orders=1) {
if(!$where){
return 0;
}
$model = new Model_Skill();
$list=$model->upOrsers($where,$orders);
return 1;
}
/* 技能信息 */
public function getSkill($id) {
$info=[];
$list=$this->getSkillList();
foreach($list as $k=>$v){
if($v['id']==$id){
$info=$v;
break;
}
}
return $info;
}
/* 技能段位 */
public function getLevel($skillid) {
$key='skillLevel_'.$skillid;
$list=\App\getcaches($key);
if(!$list){
$model = new Model_Skill();
$list=$model->getLevel($skillid);
if($list){
\App\setcaches($key,$list);
}
}
foreach($list as $k=>$v){
if(\PhalApi\DI()->lang=='en' && $v['name_en']!=''){
$v['name']=$v['name_en'];
}
unset($v['name_en']);
$list[$k]=$v;
}
return $list;
}
/* 某段位信息 */
public function getLevelInfo($skillid,$levelid) {
$levellist=$this->getLevel($skillid);
$level=[];
foreach($levellist as $k=>$v){
if($levelid==$v['levelid']){
$level=$v;
break;
}
}
return $level;
}
/* 技能标签 */
public function getLabel($skillid,$ifunset=1) {
$key='skillLabel_'.$skillid;
$list=\App\getcaches($key);
if(!$list){
$model = new Model_Skill();
$list=$model->getLabel($skillid);
if($list){
\App\setcaches($key,$list);
}
}
if($ifunset){
foreach($list as $k=>$v){
if(\PhalApi\DI()->lang=='en' && $v['name_en']!=''){
$v['name']=$v['name_en'];
}
unset($v['name_en']);
$list[$k]=$v;
}
}
return $list;
}
/* 技能标签统计 */
public function getLabelNums($uid,$skillid) {
$model = new Model_Skill();
$list=$model->getLabelNums($uid,$skillid);
$labellist=$this->getLabel($skillid);
foreach($list as $k=>$v){
$label='';
foreach($labellist as $k1=>$v1){
if($v['labelid']==$v1['id']){
$label=$v1['name'];
}
}
$v['label']=$label;
$list[$k]=$v;
}
return $list;
}
/* 更新技能标签统计 */
public function upLabelNums($uid,$skillid,$labelid) {
$model = new Model_Skill();
$list=$model->upLabelNums($uid,$skillid,$labelid);
return $list;
}
/* 用户单技能信息 */
public function getAuthInfo($where) {
$model = new Model_Skill();
$info=$model->getAuthInfo($where);
return $info;
}
/* 用户技能列表 */
public function getSkillAuth($where,$order='id desc') {
$model = new Model_Skill();
$list=$model->getSkillAuth($where,$order);
foreach($list as $k=>$v){
$v=$this->handelAuth($v);
$list[$k]=$v;
}
return $list;
}
/* 技能下用户列表 */
public function getUserList($uid,$skillid,$order='0',$sex='0',$level='0',$voice='0') {
$where=[];
$where['status']='1';
$where['switch']='1';
$where['skillid']=$skillid;
$where['uid!=?']=$uid;
if($sex!=0){
$where['sex']=$sex;
}
if($level!='0'){
$where['levelid']=$level;
}
if($voice!=0){
$where['voice !=?']='';
}
$model = new Model_Skill();
if($order!=0){
$order='uptime desc';
$list=$model->getSkillAuth($where,$order);
}else{
$list=$model->getRecomAuth($where);
}
foreach($list as $k=>$v){
$v=$this->handelAuth($v);
$userinfo=\App\getUserInfo($v['uid']);
if($userinfo['user_status']=='3'){
unset($list[$k]);
continue;
}
unset($userinfo['birthday']);
$v['userinfo']=$userinfo;
unset($v['thumb']);
unset($v['switch']);
unset($v['label']);
unset($v['voice']);
// unset($v['des']);
unset($v['recom']);
$list[$k]=$v;
}
$list=array_values($list);
return $list;
}
/* 技能主页 */
public function getSkillHome($uid,$liveuid,$skillid){
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$skillinfo=$this->getSkill($skillid);
if(!$skillinfo){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('技能不存在');
return $rs;
}
$where_a=[];
$where_a['uid']=$liveuid;
$where_a['skillid']=$skillid;
$where_a['switch']='1';
$order_a='id desc';
$auth=$this->getSkillAuth($where_a,$order_a);
if(!$auth){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('对方未认证此技能');
return $rs;
}
$authinfo=$auth[0];
$label=$this->getLabelNums($liveuid,$skillid);
$Domain_Comment=new Domain_Comment();
$where_c=[];
$where_c['liveuid']=$liveuid;
$where_c['skillid']=$skillid;
$order_c='id desc';
$comment_nums=$Domain_Comment->getCommentNums($where_c);
$comment_list=$Domain_Comment->getComment(1,$where_c,$order_c);
$info=\App\getUserInfo($liveuid);
unset($info['birthday']);
$isattent=\App\isAttent($uid,$liveuid);
$info['isattent']=$isattent;
$info['skill']=$skillinfo;
$info['authinfo']=$auth[0];
$info['label_list']=$label;
$info['comment_nums']=$comment_nums;
$info['comment_list']=$comment_list;
$rs['info'][0]=$info;
return $rs;
}
protected function handelAuth($v){
$v['thumb']=\App\get_upload_path($v['thumb']);
$v['voice']=\App\get_upload_path($v['voice']);
$v['star_level']=(string)round($v['stars']);
$label_a=preg_split('/;|/',$v['label']);
$label_a=array_filter($label_a);
$label=[];
$labellist=$this->getLabel($v['skillid']);
foreach($label_a as $k1=>$v1){
foreach($labellist as $k2=>$v2){
if($v1==$v2['id']){
$label[]=$v2['name'];
}
}
}
$v['label_a']=$label;
$skillinfo=$this->getSkill($v['skillid']);
$v['method']=isset($skillinfo['method']) ? $skillinfo['method'] : '';
$v['skillname']=isset($skillinfo['name']) ? $skillinfo['name'] : '';
/* 段位 */
$levelinfo=$this->getLevelInfo($v['skillid'],$v['levelid']);
$level=isset($levelinfo['name']) ? $levelinfo['name'] : '';
$v['level']=$level;
unset($v['label']);
unset($v['status']);
unset($v['reason']);
unset($v['addtime']);
unset($v['uptime']);
unset($v['star']);
unset($v['comments']);
return $v;
}
/* 某技能认证信息 */
public function getSkillInfo($liveuid,$skillid){
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$skillinfo=$this->getSkill($skillid);
if(!$skillinfo){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('技能不存在');
return $rs;
}
$where_a=[];
$where_a['uid']=$liveuid;
$where_a['skillid']=$skillid;
$where_a['status']='1';
$order_a='id desc';
$auth=$this->getSkillAuth($where_a,$order_a);
if(!$auth){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('对方未认证此技能');
return $rs;
}
$authinfo=$auth[0];
/* if($authinfo['switch']!=1){
$rs['code'] = 1003;
$rs['msg'] = \PhalApi\T('对方未开启此技能');
return $rs;
} */
$info['skill']=$skillinfo;
$info['authinfo']=$auth[0];
$rs['info'][0]=$info;
return $rs;
}
/* 我的技能列表 */
public function getMyskillList($uid){
$where=[];
$where['uid']=$uid;
$where['status']=1;
$where['switch']=1;
$order='id desc';
$model = new Model_Skill();
$list=$model->getMyskillList($where,$order);
return $list;
}
/* 我的技能列表 */
public function getByidslist($where){
$model = new Model_Skill();
$list=$model->getByidslist($where);
return $list;
}
/* 最新认证技能 */
public function getNewSkillauth($uid){
$where=[];
$where['uid']=$uid;
$where['status']=1;
$where['switch']=1;
$order='id desc';
$model = new Model_Skill();
$list=$model->getNewSkillauth($where,$order);
return $list;
}
}

View File

@ -0,0 +1,576 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Domain;
use App\Model\User as Model_User;
use App\Domain\Skill as Domain_Skill;
class User {
/* 用户基本信息 */
public function getBaseInfo($uid) {
$model = new Model_User();
$info = $model->getBaseInfo($uid);
if($info){
$info=\App\handleUser($info);
$info['follows']=\App\getFollowNum($uid);
$info['fans']=\App\getFansNum($uid);
unset($info['birthday']);
}
return $info;
}
/* 是否实名认证 */
public function isauth($uid) {
$model = new Model_User();
$rs = $model->isauth($uid);
return $rs;
}
/* 更新基本信息 */
public function upUserInfo($uid,$fields=[]) {
$rs = array('code' => 0, 'msg' => \PhalApi\T('操作成功'), 'info' => array());
$model = new Model_User();
$data=[];
$info=[];
/* 头像 */
if( isset($fields['avatar']) && $fields['avatar']!='' ){
//$avatar_q=$fields['avatar'];
$avatar_q=\App\set_upload_path($fields['avatar']);
$configpri=\App\getConfigPri();
$cloudtype=$configpri['cloudtype'];
if(!strstr($avatar_q,'?') && $cloudtype=='1'){//1七牛云存储2亚马逊存储
$avatar= $avatar_q.'?imageView2/2/w/600/h/600'; //600 X 600
$avatar_thumb= $avatar_q.'?imageView2/2/w/200/h/200'; // 200 X 200
}else{
$avatar=$avatar_q;
$avatar_thumb=$avatar_q;
}
$data['avatar']=$avatar;
$data['avatar_thumb']=$avatar_thumb;
$info['avatar']=\App\get_upload_path($avatar);
$info['avatar_thumb']=\App\get_upload_path($avatar_thumb);
}
/* 昵称 */
if( isset($fields['user_nickname']) && $fields['user_nickname']!='' ){
$name=$fields['user_nickname'];
$count=mb_strlen($name);
if($count>10){
$rs['code'] = 1002;
$rs['msg'] = \PhalApi\T('昵称最多10个字');
return $rs;
}
$isexist = $model->checkNickname($uid,$name);
if($isexist){
$rs['code'] = 1003;
$rs['msg'] = \PhalApi\T('昵称已存在');
return $rs;
}
$data['user_nickname']=$name;
$info['user_nickname']=$name;
}
/* 声音 */
if( isset($fields['voice']) && $fields['voice']!='' ){
// $voice=$fields['voice'];
if($fields['voice']){
$voice=\App\set_upload_path($fields['voice']);
}else{
$voice=$fields['voice'];
}
$voice_l=$fields['voice_l'];
$data['voice']=$voice;
$data['voice_l']=$voice_l;
$info['voice']=\App\get_upload_path($voice);
$info['voice_l']=$voice_l;
}else{
$data['voice']="";
$data['voice_l']=0;
$info['voice']="";
$info['voice_l']=0;
}
/* 生日 年龄 星座 */
if( isset($fields['birthday']) && $fields['birthday']!='' ){
$birthday=strtotime($fields['birthday']);
$age=\App\getAge($birthday);
$constellation=\App\getConstellation($birthday);
$data['birthday']=$birthday;
$info['birthday']=$birthday;
$info['age']=$age;
$info['constellation']=$constellation;
}
/* 性别 */
if( isset($fields['sex']) && $fields['sex']!='' ){
$sex=$fields['sex'];
$isexist = $model->checkSex($uid);
if(!$isexist){
$data['sex']=$sex;
$info['sex']=$sex;
}
}
/* 家乡 */
if( isset($fields['addr'])){
if($fields['addr']!=''){
$addr=$fields['addr'];
$data['addr']=$addr;
$info['addr']=$addr;
}else{
$data['addr']="";
$info['addr']="";
}
}
/* 签名 */
if( isset($fields['signature'])){
if($fields['signature']!=''){
$signature=$fields['signature'];
$data['signature']=$signature;
$info['signature']=$signature;
}else{
$data['signature']="";
$info['signature']="";
}
}
/* 职业 */
if( isset($fields['profession']) ){
if($fields['profession']!=''){
$profession=$fields['profession'];
$data['profession']=$profession;
$info['profession']=$profession;
}else{
$data['profession']="";
$info['profession']="";
}
}
/* 学校 */
if( isset($fields['school'])){
if($fields['school']!=''){
$school=$fields['school'];
$data['school']=$school;
$info['school']=$school;
}else{
$data['school']="";
$info['school']="";
}
}
if(!$data){
$rs['code'] = 1003;
$rs['msg'] = \PhalApi\T('信息错误');
return $rs;
}
$result = $model->upUserInfo($uid,$data);
\App\delcache("userinfo_".$uid);
$rs['info'][0]=$info;
return $rs;
}
/* 更新星级 */
public function upStar($uid,$stars,$nums){
$model = new Model_User();
$res=$model->upStar($uid,$stars,$nums);
return $res;
}
/* 关注、取关 */
public function setAttent($uid,$touid){
$model = new Model_User();
$isattent=\App\isAttent($uid,$touid);
if($isattent){
/* 已关注 取消 */
$model->delAttent($uid,$touid);
$isattent='0';
}else{
/* 未关注 关注 */
$model->setAttent($uid,$touid);
$isattent='1';
}
return $isattent;
}
/* 关注列表 */
public function getFollow($uid,$touid,$p){
$where=[
'uid'=>$touid
];
$model = new Model_User();
$list = $model->getAttention($where,$p);
foreach($list as $k=>$v){
$userinfo=\App\getUserInfo($v['touid']);
unset($userinfo['birthday']);
$isattent='0';
if($uid==$touid){
$isattent='1';
}else{
$isattent=\App\isAttent($uid,$v['touid']);
}
$userinfo['isattent']=$isattent;
$list[$k]=$userinfo;
}
return $list;
}
/* 用户列表
* type 类型 0推荐 1关注 2最新
*/
public function getList($uid,$sex,$age,$skillid,$p,$type=0) {
$uids_s='';
$attent_a=[];
$model = new Model_User();
$where='user_status=1 and user_type=2 ';
if($type==1){
$where1=[
'uid'=>$uid,
];
$order1='addtime desc';
$attentlist = $model->getAllAttention($where1,$order1);
if(!$attentlist){
return [];
}
$attent_a=array_column($attentlist,'touid');
$attent_s=implode(',',$attent_a);
$uids_s=$attent_s;
if($uids_s){
$where.=" and id in ({$uids_s})";
}
}
// $where='status=1 and (type=1 or type=2)';
$Domain_Skill = new Domain_Skill();
if($sex!=0){
if($sex==1){
$where.=' and sex=1';
}else{
$where.=' and sex!=1';
}
}
if($age!=0){
$time=\App\getAges($age);
if(!$time){
return [];
}
$where.=" and birthday>={$time[0]} and birthday<{$time[1]}";
}
if($skillid!=0){
$where3="skillid={$skillid} and status=1 and switch=1";
$skillids=$Domain_Skill->getByidslist($where3);
if(!$skillids){
return [];
}
$killuser_a=array_column($skillids,'uid');
$killuser_s=implode(',',$killuser_a);
$uids_s1=$killuser_s;
if($uids_s1){
$where.=" and id in ({$uids_s1})";
}
}
if($type==0){//推荐
$order='recommend_time desc,orders desc';
}else if($type==2){//最新认证成功的用户(最近三天)
}
$list= $model->getList($where,$order,$p,$type);
foreach($list as $k=>$v){
// $skill_list=$Domain_Skill->getMyskillList($v['id']);
$skillinfo=$Domain_Skill->getNewSkillauth($v['id']);
$v['skill_des']="陪练的亲亲们都敲厉害哒!";
if($skillinfo){
if($skillinfo['des']){
$v['skill_des']=$skillinfo['des'];
}
unset($skillinfo['des']);
$v['skillinfo']=$skillinfo;
}else{
$v['skillinfo']=(Object)array();
}
$list[$k]=$v;
}
return $list;
}
/* 所有关注、粉丝用户 */
public function getAllAttention($where){
$model = new Model_User();
$list = $model->getAllAttention($where);
return $list;
}
/* 粉丝列表 */
public function getFans($uid,$touid,$p){
$where=[
'touid'=>$touid
];
$model = new Model_User();
$list = $model->getAttention($where,$p);
foreach($list as $k=>$v){
$userinfo=\App\getUserInfo($v['uid']);
unset($userinfo['birthday']);
$isattent=\App\isAttent($uid,$v['uid']);
$userinfo['isattent']=$isattent;
$list[$k]=$userinfo;
}
return $list;
}
/* 个人主页 */
public function getHome($uid,$touid){
$info=\App\getUserInfo($touid);
$isattent=\App\isAttent($uid,$touid);
$info['isattent']=$isattent;
$info['fans']=\App\getFansNum($touid);
$des=[];
if($info['addr']){
$des[]=\PhalApi\T('来自{n}',[ 'n'=>$info['addr'] ]);
}
if($info['birthday']){
$y=date('y',$info['birthday']);
$y0=substr($y,0,1).'0';
$sex=\PhalApi\T('女生');
if($info['sex']==1){
$sex=\PhalApi\T('男生');
}
$des[]=\PhalApi\T('{n}后',['n'=>$y0]).$info['constellation'].$sex;
}
unset($info['birthday']);
if($info['hobby']){
$hobby=explode(';',$info['hobby']);
$hobby=array_filter($hobby);
$des[]=\PhalApi\T('喜欢{n}',[ 'n'=>implode('/',$hobby) ]);
}
if($info['profession']){
$des[]=\PhalApi\T('从事{n}',[ 'n'=>$info['profession'] ]);
}
if($info['school']){
$des[]=\PhalApi\T('毕业于{n}',[ 'n'=>$info['school'] ]);
}
$info['des']=implode('',$des);
/* 技能 */
$where=[
'uid'=>$touid,
'status'=>'1',
'switch'=>'1',
];
$order='id desc';
if($info['user_status']=='3'){
$info['list']=array();
}else{
$Domain_Skill = new Domain_Skill();
$list = $Domain_Skill->getSkillAuth($where);
$info['list']=$list;
}
return $info;
}
/* 根据条件获取用户ID */
public function getUsers($where){
$model = new Model_User();
$list = $model->getUsers($where);
return $list;
}
/* 检测关系 */
public function checkAttent($uid,$touid){
$status='0';
$isattent1=\App\isAttent($uid,$touid);
if($isattent1){
$status='1';
}
$isattent2=\App\isAttent($touid,$uid);
if($isattent2){
$status='2';
}
if($isattent1 && $isattent2){
$status='3';
}
return $status;
}
/* 检测是否主持人 */
public function ishost($uid){
$model = new Model_User();
$rs = $model->ishost($uid);
return $rs;
}
/* 最新认证用户列表(最近三天)
* type 类型 0推荐 1关注 2最新
*/
public function getAuthlist($uid,$p,$type=2) {
$rs = array('code' => 0, 'msg' => '', 'info' => array());
$uids_s='';
$attent_a=[];
$model = new Model_User();
$where='user_status=1 and user_type=2 ';
$Domain_Skill = new Domain_Skill();
$threedaystime=time()-3*24*60*60;
$where2="status=1 and uptime > {$threedaystime}";
$order2='uptime desc';
$authlist = $model->getAuthlist($where2,$order2);
if(!$authlist){
$auth_s=0;
}else{
$auth_a=array_column($authlist,'uid');
$auth_s=implode(',',$auth_a);
}
$uids_s2=$auth_s;
// if($uids_s2){
$where.=" and id in ({$uids_s2})";
// }
$list= $model->getList($where,$order,$p,$type);
$rs['info'][0]['next_p']=$p+1;
if(!$list){
$list=[];
if($p>1){
$list=$model->getList($where,$order,1,$type);
$rs['info'][0]['next_p']=2;
}else{
$rs['msg']="没有更多新人~";
$rs['info'][0]['next_p']=1;
}
}
foreach($list as $k=>$v){
// $skill_list=$Domain_Skill->getMyskillList($v['id']);
$skillinfo=$Domain_Skill->getNewSkillauth($v['id']);
$v['skill_des']="陪练的亲亲们都敲厉害哒!";
if($skillinfo){
if($skillinfo['des']){
$v['skill_des']=$skillinfo['des'];
}
unset($skillinfo['des']);
$v['skillinfo']=$skillinfo;
}else{
$v['skillinfo']=(Object)array();
}
$list[$k]=$v;
}
$rs['info'][0]['list']=$list;
return $rs;
}
}

View File

@ -0,0 +1,110 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Cash extends NotORM {
/* 我的:订单收益 */
public function getProfit($uid){
$info= \PhalApi\DI()->notorm->user
->select("votes,votestotal")
->where('id=?',$uid)
->fetchOne();
return $info;
}
/* 本月提现次数 */
public function getCashNums($uid){
$nowtime=time();
//本月第一天
$month=date('Y-m-d',strtotime(date("Ym",$nowtime).'01'));
$month_start=strtotime(date("Ym",$nowtime).'01');
//本月最后一天
$month_end=strtotime("{$month} +1 month");
$nums=\PhalApi\DI()->notorm->cash_record
->where('uid=? and addtime > ? and addtime < ?',$uid,$month_start,$month_end)
->count();
return $nums;
}
/* 扣除:订单收益映票 */
public function upVotes($uid,$votes){
$rs=\PhalApi\DI()->notorm->user
->where('id = ? and votes>=?', $uid,$votes)
->update(array('votes' => new \NotORM_Literal("votes - {$votes}")) );
return $rs;
}
public function getVotes($uid){
$info=\PhalApi\DI()->notorm->user
->select("votes_gift,votes")
->where('id = ?',$uid)
->fetchOne();
return $info;
}
/* 提现 */
public function setCash($data){
$rs=\PhalApi\DI()->notorm->cash_record->insert($data);
return $rs;
}
/* 提现账号列表 */
public function getUserAccountList($uid){
$list=\PhalApi\DI()->notorm->cash_account
->select("*")
->where('uid=?',$uid)
->order("addtime desc")
->fetchAll();
return $list;
}
/* 提现账号详情 */
public function getAccount($id){
$info=\PhalApi\DI()->notorm->cash_account
->select("*")
->where('id=?',$id)
->fetchOne();
return $info;
}
/* 设置提账号 */
public function setUserAccount($data){
$rs=\PhalApi\DI()->notorm->cash_account
->insert($data);
return $rs;
}
/* 删除提账号 */
public function delUserAccount($data){
$rs=\PhalApi\DI()->notorm->cash_account
->where($data)
->delete();
return $rs;
}
}

View File

@ -0,0 +1,45 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Charge extends NotORM {
/* 充值规则列表 */
public function getChargeRules() {
$rules=\PhalApi\DI()->notorm->charge_rules
->select('id,name,money,coin,coin_ios,coin_paypal,product_id')
->order('list_order asc')
->fetchAll();
return $rules;
}
/* 获取充值规则 */
public function getChargeRule($changeid) {
$charge=\PhalApi\DI()->notorm->charge_rules->select('*')->where('id=?',$changeid)->fetchOne();
return $charge;
}
/* 订单号 */
public function setOrder($orderinfo) {
$result= \PhalApi\DI()->notorm->charge_user->insert($orderinfo);
return $result;
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Comment extends NotORM {
/* 设置主播评论 */
public function setComment($data) {
$result= \PhalApi\DI()->notorm->skill_comment->insert($data);
return $result;
}
/* 设置用户评论 */
public function setEvaluate($data) {
$result= \PhalApi\DI()->notorm->user_comment->insert($data);
return $result;
}
/* 技能评论总数 */
public function getCommentNums($where){
$nums=\PhalApi\DI()->notorm->skill_comment
->where($where)
->count();
return $nums;
}
/* 技能评论 */
public function getComment($p,$where,$order){
if($p<1){
$p=1;
}
$nums=20;
$start=($p-1) * $nums;
$list=\PhalApi\DI()->notorm->skill_comment
->select('*')
->where($where)
->order($order)
->limit($start,$nums)
->fetchAll();
return $list;
}
/* 评论内容 */
public function getCommentInfo($where){
$info=\PhalApi\DI()->notorm->skill_comment
->select('*')
->where($where)
->fetchOne();
return $info;
}
/* 评论内容 */
public function getEvaluateInfo($where){
$info=\PhalApi\DI()->notorm->user_comment
->select('*')
->where($where)
->fetchOne();
return $info;
}
}

View File

@ -0,0 +1,46 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Guide extends NotORM {
/* 引导页 */
public function getGuide() {
$config=\PhalApi\DI()->notorm->option
->select('option_value')
->where("option_name='guide'")
->fetchOne();
$config = json_decode($config['option_value'],true);
$where="type={$config['type']}";
$list=\PhalApi\DI()->notorm->guide
->select('thumb,href')
->where($where)
->order('list_order asc,uptime desc')
->fetchAll();
foreach($list as $k=>$v){
$v['thumb']=\App\get_upload_path($v['thumb']);
$v['href']=urldecode($v['href']);
$list[$k]=$v;
}
$config['list']=$list;
return $config;
}
}

View File

@ -0,0 +1,84 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Home extends NotORM {
/* 轮播 */
public function getSilide($id) {
$list=\PhalApi\DI()->notorm->slide_item
->select('id,title,image,url')
->where('status=1 and slide_id=?',$id)
->order('list_order asc')
->fetchAll();
return $list;
}
/* 用户列表 */
public function getUsers($uid,$p) {
if($p<1){
$p=1;
}
$nums=20;
$start=($p-1) * $nums;
$list=\PhalApi\DI()->notorm->user
->select('id,user_nickname,avatar,avatar_thumb,sex,birthday,profession,addr')
->where('user_type=2 and user_status!=0 and isswitch=1 and id!=?',$uid)
->order('online desc,orders desc')
->limit($start,$nums)
->fetchAll();
return $list;
}
/* 搜索技能 */
public function searchSkill($keyword) {
$list=\PhalApi\DI()->notorm->skill
->select('*')
->where('name like ?','%'.$keyword.'%')
->order('list_order asc')
->fetchAll();
return $list;
}
/* 搜索用户 */
public function searchUser($keyword,$p) {
if($p<1){
$p=1;
}
$nums=20;
$start=($p-1) * $nums;
$list=\PhalApi\DI()->notorm->user
->select('id,user_nickname,avatar,avatar_thumb,sex,birthday')
// ->where('user_type=2 and user_status!=0 and user_status!=3 ')
->where('user_type=2 and user_status not in(0,3) ')
->where('id like ? or user_nickname like ?','%'.$keyword.'%','%'.$keyword.'%')
->order('online desc,orders desc')
->limit($start,$nums)
->fetchAll();
return $list;
}
}

View File

@ -0,0 +1,65 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Im extends NotORM {
/* 官方公告 */
public function getSysNotice($uid,$p) {
if($p<1){
$p=1;
}
$pnum=50;
$start=($p-1)*$uid;
//读取用户创建时间
$userinfo=\PhalApi\DI()->notorm->user
->select("create_time")
->where('id =? ',$uid)
->fetchOne();
$list=\PhalApi\DI()->notorm->sys_notice
->select("*")
->where("addtime > ?",$userinfo['create_time'])
->limit($start,$pnum)
->order('id desc')
->fetchAll();
//记录最后一次访问该接口的时间
if($list){
$isexist=\PhalApi\DI()->notorm->sys_notice_readtime
->where('uid =? ',$uid)
->fetchOne();
if($isexist){
\PhalApi\DI()->notorm->sys_notice_readtime
->where("uid=?",$uid)
->update(array("addtime"=>time()));
}else{
$data=array(
"uid"=>$uid,
"addtime"=>time()
);
\PhalApi\DI()->notorm->sys_notice_readtime
->insert($data);
}
}
return $list;
}
}

View File

@ -0,0 +1,125 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Login extends NotORM {
protected $fields='id,user_nickname,avatar,avatar_thumb,sex,signature,coin,votes,birthday,user_status,login_type,last_login_time,profession,school,hobby,voice,voice_l,addr,stars,star_nums,orders,consumption,votestotal,votes_gifttotal';
/* 会员登录 */
public function userLogin($where) {
$info=\PhalApi\DI()->notorm->user
->select($this->fields)
->where('user_type=2')
->where($where)
->fetchOne();
return $info;
}
/* 会员注册 */
public function userReg($data=[]) {
$nowtime=time();
$user_pass='yuewan'.$nowtime;
$user_pass=\App\setPass($user_pass);
$avatar='/default.png';
$avatar_thumb='/default_thumb.png';
$configpri=\App\getConfigPri();
$reg_reward=$configpri['reg_reward'];
$default=array(
'user_pass' =>$user_pass,
'signature' =>'',
'avatar' =>$avatar,
'avatar_thumb' =>$avatar_thumb,
'last_login_ip' =>\PhalApi\Tool::getClientIp(),
'create_time' => $nowtime,
'user_status' => 1,
"user_type"=>2,//会员
"coin"=>$reg_reward,
);
if(isset($data['user_pass'])){
$data['user_pass']=\App\setPass($data['user_pass']);
}
$insert=array_merge($default,$data);
$rs=\PhalApi\DI()->notorm->user->insert($insert);
$id=$rs['id'];
if($reg_reward>0){
$insert=array("type"=>'1',"action"=>'11',"uid"=>$id,"touid"=>$id,"actionid"=>0,"nums"=>1,"total"=>$reg_reward,"addtime"=>time() );
\PhalApi\DI()->notorm->user_coinrecord->insert($insert);
}
$info=\PhalApi\DI()->notorm->user
->select($this->fields)
->where('id=?',$id)
->fetchOne();
return $info;
}
/* 更新token 登陆信息 */
public function updateToken($uid,$token,$data=array()) {
$nowtime=time();
$expiretime=$nowtime+60*60*24*150;
\PhalApi\DI()->notorm->user
->where('id=?',$uid)
->update(array('last_login_time' => $nowtime, "last_login_ip"=>\PhalApi\Tool::getClientIp() ));
$token_info=array(
'user_id'=>$uid,
'token'=>$token,
'expire_time'=>$expiretime,
'create_time'=>$nowtime,
);
$isexist=\PhalApi\DI()->notorm->user_token
->where('user_id=?',$uid)
->update( $token_info );
if(!$isexist){
\PhalApi\DI()->notorm->user_token
->insert( $token_info );
}
\App\hMSet("token_".$uid,$token_info);
return 1;
}
public function getcashRecord(){
$recordlist=\PhalApi\DI()->notorm->cash_record
->where("uid=? and status=0",$uid)
->fetchAll();
return $recordlist;
}
public function getOrderlist($uid){
$list=\PhalApi\DI()->notorm->orders
->where("(uid=? or liveuid=?) and status in(0,2,3,4,6)",$uid,$uid)
->select("id,uid,status")
->fetchAll(); //0待支付2已接单3:等待退款4拒绝退款6退款申诉
return $list;
}
}

View File

@ -0,0 +1,100 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Orders extends NotORM {
/* 进行中 */
public function getOrdersing($where,$order='id desc') {
$nowtime=time();
$addtime=$nowtime - 60*60*24*30*3;
$list=\PhalApi\DI()->notorm->orders
->select('*')
->where($where)
->where('addtime >= ?',$addtime)
->order($order)
->fetchAll();
return $list;
}
/* 订单列表 */
public function getOrders($p,$where,$order='id desc') {
$nowtime=time();
$addtime=$nowtime - 60*60*24*30*3;
if($p<1){
$p=1;
}
$nums=20;
$start=($p-1) * $nums;
$list=\PhalApi\DI()->notorm->orders
->select('*')
->where($where)
->where('addtime >= ?',$addtime)
->order($order)
->limit($start,$nums)
->fetchAll();
return $list;
}
/* 取消原因 */
public function getCancelList(){
$list=\PhalApi\DI()->notorm->orders_cancel
->select('*')
->order('list_order asc')
->fetchAll();
return $list;
}
/* 获取订单信息 */
public function getOrderInfo($where) {
$info=\PhalApi\DI()->notorm->orders->select('*')->where($where)->order("id desc")->fetchOne();
return $info;
}
/* 获取部分订单信息 */
public function getSomeOrderInfo($where) {
$info=\PhalApi\DI()->notorm->orders->select('id,svctm,uid,liveuid,status,recept_status,order_type')->where($where)->order("id asc")->fetchOne();
return $info;
}
/* 生成订单 */
public function setOrder($orderinfo) {
$result= \PhalApi\DI()->notorm->orders->insert($orderinfo);
return $result;
}
/* 更新订单 */
public function upOrder($where,$data) {
$result= \PhalApi\DI()->notorm->orders->where($where)->update($data);
return $result;
}
}

View File

@ -0,0 +1,249 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class Skill extends NotORM {
/* 技能分类 */
public function getClass() {
$list=\PhalApi\DI()->notorm->skill_class
->select('id,name,name_en')
->order('list_order asc')
->fetchAll();
return $list;
}
/* 技能列表 */
public function getSkillList() {
$list=\PhalApi\DI()->notorm->skill
->select('*')
->order('classid asc,list_order asc')
->fetchAll();
return $list;
}
/* 技能段位 */
public function getLevel($skillid) {
$list=\PhalApi\DI()->notorm->skill_level
->select('levelid,name,name_en')
->where('skillid=?',$skillid)
->order('levelid asc')
->fetchAll();
return $list;
}
/* 价格列表 */
public function getCoinList() {
$list=\PhalApi\DI()->notorm->skill_coin
->select('*')
->order('coin asc')
->fetchAll();
return $list;
}
/* 认证的技能 */
public function getAuthInfo($where) {
$info=\PhalApi\DI()->notorm->skill_auth
->select('*')
->where($where)
->fetchOne();
return $info;
}
/* 认证的技能 */
public function getSkillAuth($where,$order) {
$list=\PhalApi\DI()->notorm->skill_auth
->select('*')
->where($where)
->order($order)
->fetchAll();
return $list;
}
/* 认证的技能 -智能排序 */
public function getRecomAuth($where) {
$configpri=\App\getConfigPri();
$skill_recom_star=floatval($configpri['skill_recom_star']);
$skill_recom_orders=floatval($configpri['skill_recom_orders']);
$skill_recom_coin=floatval($configpri['skill_recom_coin']);
$list=\PhalApi\DI()->notorm->skill_auth
->select("*,floor( ( stars * {$skill_recom_star} + orders * {$skill_recom_orders} + coin * {$skill_recom_coin} ) * 100 ) as recom")
->where($where)
->order('recom desc')
->fetchAll();
return $list;
}
/* 更新我的技能信息 */
public function upSkill($where,$data) {
$rs=\PhalApi\DI()->notorm->skill_auth
->where($where)
->update($data);
return $rs;
}
/* 更新星级、评论 */
public function upStar($where,$star=1,$comments=1) {
$rs=\PhalApi\DI()->notorm->skill_auth
->where($where)
->update(['star' => new \NotORM_Literal("star + {$star}"),'comments' => new \NotORM_Literal("comments + {$comments}")]);
if($rs){
$info=\PhalApi\DI()->notorm->skill_auth
->select('star,comments')
->where($where)
->fetchOne();
$stars=\App\getLevel($info['star'],$info['comments']);
\PhalApi\DI()->notorm->skill_auth
->where($where)
->update(['stars' => $stars]);
}
return $rs;
}
/* 更新订单数 */
public function upOrsers($where,$orders=1) {
$rs=\PhalApi\DI()->notorm->skill_auth
->where($where)
->update(['orders' => new \NotORM_Literal("orders + {$orders}")]);
\PhalApi\DI()->notorm->user
->where('id=?',$where['uid'])
->update(['orders' => new \NotORM_Literal("orders + {$orders}")]);
return $rs;
}
/* 更新用户表状态 */
public function upUserSwitch($uid,$isswitch) {
$rs=\PhalApi\DI()->notorm->user
->where('id=?',$uid)
->update(['isswitch'=>$isswitch]);
return $rs;
}
/* 技能标签 */
public function getLabel($skillid) {
$list=\PhalApi\DI()->notorm->label
->select('id,name,name_en')
->where('skillid=?',$skillid)
->order('list_order asc')
->fetchAll();
return $list;
}
/* 技能标签统计 */
public function getLabelNums($uid,$skillid) {
$list=\PhalApi\DI()->notorm->label_count
->select('*')
->where('uid=? and skillid=?',$uid,$skillid)
->order('nums desc')
->fetchAll();
return $list;
}
/* 更新标签统计 */
public function upLabelNums($uid,$skillid,$labelid) {
$list=\PhalApi\DI()->notorm->label_count
->where('uid=? and skillid=? and labelid=?',$uid,$skillid,$labelid)
->update( array('nums' => new \NotORM_Literal("nums + 1") ) );
if(!$list){
\PhalApi\DI()->notorm->label_count->insert(['uid'=>$uid,'skillid'=>$skillid,'labelid'=>$labelid,'nums'=>1]);
}
return 1;
}
/* 技能详情 */
public function getMyskillList($where,$order) {
$list=\PhalApi\DI()->notorm->skill_auth
->select('id,skillid,status,switch')
->where($where)
->order($order)
->fetchAll();
foreach($list as $k1=>$v1){
$skillinfo=\PhalApi\DI()->notorm->skill
->where('id=?',$v1['skillid'])
->fetchOne();
if(!$skillinfo){
unset($list[$k]);
continue;
}
$v1['skill_name']=$skillinfo['name'];
$v1['skill_thumb']=\App\get_upload_path($skillinfo['thumb']);
$list[$k1]=$v1;
}
$list=array_values($list);
return $list;
}
/* 根据技能ID获取拥有用户ID集合 */
public function getByidslist($where) {
$list=\PhalApi\DI()->notorm->skill_auth
->select('id,skillid,uid')
->where($where)
->fetchAll();
return $list;
}
/* 最新认证技能详情 */
public function getNewSkillauth($where,$order) {
$info=\PhalApi\DI()->notorm->skill_auth
->select('id,skillid,status,coin,des')
->where($where)
->order($order)
->fetchOne();
$skillinfo=\PhalApi\DI()->notorm->skill
->where('id=?',$info['skillid'])
->fetchOne();
if($skillinfo){
// $info['skillinfo']=$skillinfo;
$info['skill_name']=$skillinfo['name'];
$info['skillname']=$skillinfo['name'];
$info['skill_method']=$skillinfo['method'];
$info['method']=$skillinfo['method'];
}
return $info;
}
}

View File

@ -0,0 +1,256 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App\Model;
use PhalApi\Model\NotORMModel as NotORM;
class User extends NotORM {
/* 用户全部信息 */
public function getBaseInfo($uid) {
$info=\PhalApi\DI()->notorm->user
->select("id,user_nickname,avatar,avatar_thumb,sex,signature,coin,votes,consumption,votestotal,votes_gift,votes_gifttotal,birthday,profession,school,hobby,voice,voice_l,addr,stars,star_nums")
->where('id=? and user_type=2',$uid)
->fetchOne();
return $info;
}
/* 是否认证 */
public function isauth($uid){
$isexist=\PhalApi\DI()->notorm->user_auth
->select("uid")
->where('uid =? and status=1',$uid)
->fetchOne();
if($isexist){
return '1';
}
return '0';
}
/* 检测用户昵称 */
public function checkNickname($uid,$name){
$isexist=\PhalApi\DI()->notorm->user
->select("id")
->where('id!=? and user_nickname=?',$uid,$name)
->fetchOne();
if($isexist){
return 1;
}
return 0;
}
/* 检测性别 */
public function checkSex($uid){
$isexist=\PhalApi\DI()->notorm->user
->select("sex")
->where('id!=?',$uid)
->fetchOne();
if($isexist && $isexist['sex']!=0){
return 1;
}
return 0;
}
/* 用户信息更新 */
public function upUserInfo($uid,$data){
$rs=0;
if($data){
$rs=\PhalApi\DI()->notorm->user
->where('id=? ',$uid)
->update($data);
}
return $rs;
}
/* 更新星级 */
public function upStar($uid,$stars,$nums) {
$rs=\PhalApi\DI()->notorm->user
->where('id=?',$uid)
->update(['stars' => new \NotORM_Literal("stars + {$stars}"),'star_nums' => new \NotORM_Literal("star_nums + {$nums}")]);
$key='userinfo_'.$uid;
$info=\App\hGetAll("userinfo_".$uid);
if($info){
\App\hIncrByFloat($key,'stars',$stars);
\App\hIncrByFloat($key,'star_nums',$nums);
}
return $rs;
}
/* 设置关注 */
public function setAttent($uid,$touid){
$data=[
'uid'=>$uid,
'touid'=>$touid,
'addtime'=>time(),
];
$list=\PhalApi\DI()->notorm->user_attention
->insert($data);
return $list;
}
/* 取消关注 */
public function delAttent($uid,$touid){
$where=[
'uid'=>$uid,
'touid'=>$touid,
];
$list=\PhalApi\DI()->notorm->user_attention
->where($where)
->delete();
return $list;
}
/* 关注列表 */
public function getAttention($where,$p){
if($p<1){
$p=1;
}
$nums=50;
$start=($p-1) * $nums;
$list=\PhalApi\DI()->notorm->user_attention
->select('*')
->where($where)
->order('addtime desc')
->limit($start,$nums)
->fetchAll();
return $list;
}
/* 所有关注、粉丝用户 */
public function getAllAttention($where,$order=''){
$list=\PhalApi\DI()->notorm->user_attention
->select('*')
->where($where)
->order($order)
->fetchAll();
return $list;
}
/* 根据条件获取用户ID */
public function getUsers($where){
$list=\PhalApi\DI()->notorm->user
->select('id')
->where($where)
->fetchAll();
return $list;
}
/* 是否派单主持人 */
public function ishost($uid){
$isexist=\PhalApi\DI()->notorm->user
->select("id")
->where('id =? and ishost=1',$uid)
->fetchOne();
if($isexist){
return '1';
}
return '0';
}
/* 用户列表type0推荐1关注2最新 */
public function getList($where,$order,$p,$type='-1'){
if($p<1){
$p=1;
}
if($type=='2'){
$nums=3;
}else{
$nums=50;
}
$start=($p-1) * $nums;
if($type=='0'){
$configpri=\App\getConfigPri();
$skill_recom_star=floatval($configpri['skill_recom_star']);
$skill_recom_orders=floatval($configpri['skill_recom_orders']);
$where .=" and isauth=1";
$select_str="id,recommend_time,isauth,floor( ( orders * {$skill_recom_orders} ) * 100 ) as recom";
$order="recommend_time desc,recom desc,id desc";
}else{
$select_str="id";
}
$list=\PhalApi\DI()->notorm->user
->select($select_str)
->where($where)
->order($order)
->limit($start,$nums)
->fetchAll();
foreach($list as $k=>$v){
unset($list[$k]['recom']);
$userinfo=\App\getUserInfo($v['id']);
if($userinfo){
unset($userinfo['birthday']);
$isattent='0';
if($uid==$touid){
$isattent='1';
}else{
$isattent=\App\isAttent($uid,$v['touid']);
}
$userinfo['isattent']=$isattent;
$list[$k]=$userinfo;
}else{
unset($list[$k]);
continue;
}
}
$list=array_values($list);
return $list;
}
/* 最新认证三天的用户 */
public function getAuthlist($where,$order){
$list=\PhalApi\DI()->notorm->user_auth
->select('*')
->where($where)
->order($order)
->fetchAll();
return $list;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,309 @@
<?php
// +———————————————————————————————————
// | Created by Yunbao
// +———————————————————————————————————
// | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
// +———————————————————————————————————
// | Author: https://gitee.com/yunbaokeji
// +———————————————————————————————————
// | Date: 2022-05-28
// +———————————————————————————————————
namespace App;
/* redis */
/* redis链接 */
function connectionRedis(){
if(!isset($GLOBALS['redisdb']) || !$GLOBALS['redisdb']){
$REDIS_HOST= \PhalApi\DI()->config->get('app.REDIS_HOST');
$REDIS_AUTH= \PhalApi\DI()->config->get('app.REDIS_AUTH');
$REDIS_PORT= \PhalApi\DI()->config->get('app.REDIS_PORT');
$redis = new \Redis();
$redis -> connect($REDIS_HOST,$REDIS_PORT);
$redis -> auth($REDIS_AUTH);
$GLOBALS['redisdb']=$redis;
}
}
/* 设置缓存 */
/* function setcache($key,$info){
$config=getConfigPri();
if($config['cache_switch']!=1){
return 1;
}
$GLOBALS['redisdb']->set($key,json_encode($info));
$GLOBALS['redisdb']->expire($key, $config['cache_time']);
return 1;
} */
/**
* redis 字符串String 类型
* 将key和value对应。如果key已经存在了它会被覆盖而不管它是什么类型。
* @param $key
* @param $info
* @param $exp 过期时间
*/
function setcaches($key,$info,$time=0){
$GLOBALS['redisdb']->set($key,json_encode($info));
if($time > 0){
$GLOBALS['redisdb']->expire($key, $time);
}
return 1;
}
/* 获取缓存 */
/* function getcache($key){
$config=getConfigPri();
$isexist=$GLOBALS['redisdb']->Get($key);
if($config['cache_switch']!=1){
$isexist=false;
}
return json_decode($isexist,true);
} */
/**
* redis 字符串String 类型
* 返回key的value。如果key不存在返回特殊值nil。如果key的value不是string就返回错误因为GET只处理string类型的values。
* @param $key
*/
function getcaches($key){
$isexist=$GLOBALS['redisdb']->Get($key);
return json_decode($isexist,true);
}
/**
* 删除一个或多个key
* @param $keys 数组/ 数组以逗号拼接的string
*/
function delcache($key){
$isexist=$GLOBALS['redisdb']->del($key);
return 1;
}
/**
* redis 哈希表(hash)类型
* 返回哈希表 $key 中,所有的域和值。
* @param $key
*
*/
function hGetAll($key){
return $GLOBALS['redisdb']->hGetAll($key);
}
/**
* 添加一个VALUE到HASH中。如果VALUE已经存在于HASH中则返回FALSE。
* @param string $key
* @param string $hashKey
* @param string $value
*/
function hSet( $key, $hashKey, $value ) {
return $GLOBALS['redisdb']->hSet($key, $hashKey, $value);
}
/**
* redis 哈希表(hash)类型
* 批量填充HASH表。不是字符串类型的VALUE自动转换成字符串类型。使用标准的值。NULL值将被储存为一个空的字符串。
* 可以批量添加更新 value,key 不存在将创建,存在则更新值
* @param $key
* @param $fieldArr 要设置的键对值
* @return
* 当key不是哈希表(hash)类型时,返回一个错误。
*/
function hMSet($key,$fieldArr){
return $GLOBALS['redisdb']->hmset($key,$fieldArr);
}
/**
* 取得HASH中的VALUE如何HASH不存在或者KEY不存在返回FLASE。
* @param string $key
* @param string $hashKey
* @return string The value, if the command executed successfully BOOL FALSE in case of failure
*/
function hGet($key, $hashKey) {
return $GLOBALS['redisdb']->hGet($key,$hashKey);
}
/**
* 批量取得HASH中的VALUE如何hashKey不存在或者KEY不存在返回FLASE。
* @param string $key
* @param array $hashKey
*/
function hMGet( $key, $hashKeys ) {
return $GLOBALS['redisdb']->hMGet($key,$hashKeys);
}
/**
* 根据HASH表的KEY为KEY对应的VALUE自增参数VALUE。浮点型
* 推荐使用 hIncrByFloat 不推荐使用 hIncrBy(整型)
* 先用 hIncrByFloat 再使用 hIncrBy 自增无效
* @param string $key
* @param string $hashKey
* @param value 自增值 整型/小数
*/
function hIncrByFloat( $key, $hashKey, $value){
return $GLOBALS['redisdb']->hIncrByFloat( $key, $hashKey, $value);
}
/**
* 删除哈希表key中的一个指定域不存在的域将被忽略。
* @param string $key
* @param string $hashKey
*/
function hDel($key,$hashKey){
return $GLOBALS['redisdb']->hDel( $key, $hashKey);
}
/**
* 添加一个字符串值到LIST容器的顶部左侧如果KEY不存在曾创建一个LIST容器如果KEY存在并且不是一个LIST容器那么返回FLASE。
* @param string $key
* @param string $val
*/
function lPush($key,$val){
return $GLOBALS['redisdb']->lPush($key,$val);
}
/**
* 添加一个字符串值到LIST容器的底部右侧如果KEY不存在曾创建一个LIST容器如果KEY存在并且不是一个LIST容器那么返回FLASE。
*
* @param string $key
* @param string $val
*/
function rPush($key,$val){
return $GLOBALS['redisdb']->rPush($key,$val);
}
/**
* 返回LIST顶部左侧的VALUE并且从LIST中把该VALUE弹出。
* @param string $key
*/
function lPop($key){
return $GLOBALS['redisdb']->lPop($key);
}
/**
* 返回LIST底部右侧的VALUE并且从LIST中把该VALUE弹出。
* @param string $key
*/
function rPop($key){
return $GLOBALS['redisdb']->rPop($key);
}
/**
* 移除指定数量的value 0移除全部 正整数 从左侧开始移除,负数从右侧移除
* @param string $key
*/
function lRem($key,$value,$count=0){
return $GLOBALS['redisdb']->lRem($key,$value,$count);
}
/**
* 获取索引范围内的数据
* @param string $key
*/
function lRange($key,$start,$end){
return $GLOBALS['redisdb']->lRange($key,$start,$end);
}
/*
* 构建一个集合(有序集合) 可排序
* @param string $key 集合名称
* @param string $value1
* @param double $score1
* return 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
*/
function zAdd($key,$score1,$value1){
return $GLOBALS['redisdb']->zAdd($key,$score1,$value1);
}
/**
* 返回key对应的有序集合中member的score值。如果member在有序集合中不存在那么将会返回nil。
* @param string $key
* @param string $member
* @return float
*/
function zScore( $key, $member ) {
return $GLOBALS['redisdb']->zScore( $key, $member );
}
/**
* 返回key对应的有序集合中介于min和max间的元素的个数。
* @param string $key
* @param string $start
* @param string $end
* @return float
*/
function zCount( $key, $start, $end ) {
return $GLOBALS['redisdb']->zCount( $key, $start, $end );
}
/**
* 返回存储在key对应的有序集合中的元素的个数。
* @param string $key
* @return int the set's cardinality
*/
function zCard($key){
return $GLOBALS['redisdb']->zCard($key);
}
/**
* 将key对应的有序集合中member元素的scroe加上 value value可以是负值
* @param string $key
* @param float $value (double) value that will be added to the member's score
* @param string $member
* @return float the new value
* @example
* <pre>
* $redis->delete('key');
* $redis->zIncrBy('key', 2.5, 'member1'); // key or member1 didn't exist, so member1's score is to 0
* // before the increment and now has the value 2.5
* $redis->zIncrBy('key', 1, 'member1'); // 3.5
* </pre>
* member 成员的新 score 值,以字符串形式表示。
*/
function zIncrBy( $key, $value, $member ) {
return $GLOBALS['redisdb']->zIncrBy( $key, $value, $member );
}
/**
* 取得特定范围内的排序元素,0代表第一个元素,1代表第二个以此类推。-1代表最后一个,-2代表倒数第二个...
* @param string $key
* @param int $start
* @param int $end
* @param bool $withscores
* @return array Array containing the values in specified range.
* @example
* <pre>
* $redis->zAdd('key1', 0, 'val0');
* $redis->zAdd('key1', 2, 'val2');
* $redis->zAdd('key1', 10, 'val10');
* $redis->zRange('key1', 0, -1); // array('val0', 'val2', 'val10')
* // with scores
* $redis->zRange('key1', 0, -1, true); // array('val0' => 0, 'val2' => 2, 'val10' => 10)
* </pre>
* 指定区间内,带有 score (可选)的有序集成员的列表。
* zRange 根据 score 正序 zRevRange 倒序
*/
function zRange( $key, $start, $end, $withscores = null ) {
return $GLOBALS['redisdb']->zRange( $key, $start, $end, $withscores) ;
}
function zRevRange( $key, $start, $end, $withscores = null ) {
return $GLOBALS['redisdb']->zRevRange( $key, $start, $end, $withscores) ;
}
/**
* 从有序集合中删除指定的成员。
* @param string $key
* @param string $member1
* @return int Number of deleted values
*/
function zRem( $key, $member1 ) {
return $GLOBALS['redisdb']->zRem( $key, $member1 );
}

View File

@ -0,0 +1,389 @@
<?php
// 搜索关键字
$keyword = isset($_GET['keyword']) ? $_GET['keyword'] : '';
echo <<<EOT
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{$description} - {$service} - {$projectName} - 在线接口文档</title>
<link rel="stylesheet" href="https://staticfile.qnssl.com/semantic-ui/2.1.6/semantic.min.css">
<link rel="stylesheet" href="https://staticfile.qnssl.com/semantic-ui/2.1.6/components/table.min.css">
<link rel="stylesheet" href="https://staticfile.qnssl.com/semantic-ui/2.1.6/components/container.min.css">
<link rel="stylesheet" href="https://staticfile.qnssl.com/semantic-ui/2.1.6/components/message.min.css">
<link rel="stylesheet" href="https://staticfile.qnssl.com/semantic-ui/2.1.6/components/label.min.css">
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<script src="https://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script>
<script src="https://apps.bdimg.com/libs/jquery.cookie/1.4.1/jquery.cookie.min.js"></script>
</head>
<body>
<div class="row" style="margin-top: 60px;" ></div>
<div class="ui text container" style="max-width: none !important;">
<div class="ui floating message">
EOT;
echo "<h2 class='ui header'>接口:$service</h2><br/> <span class='ui teal tag label'>$description</span>";
/**
* 接口说明 & 接口参数
*/
echo <<<EOT
<div class="ui raised segment">
<span class="ui red ribbon label">接口说明</span>
<div class="ui message">
<p>{$descComment}</p>
</div>
</div>
<h3><i class="sign in alternate icon"></i>接口参数</h3>
<table class="ui red celled striped table" >
<thead>
<tr><th>参数名字</th><th>类型</th><th>是否必须</th><th>默认值</th><th>其他</th><th>说明</th></tr>
</thead>
<tbody>
EOT;
$typeMaps = array(
'string' => '字符串',
'int' => '整型',
'float' => '浮点型',
'boolean' => '布尔型',
'date' => '日期',
'array' => '数组',
'fixed' => '固定值',
'enum' => '枚举类型',
'object' => '对象',
);
foreach ($rules as $key => $rule) {
$name = $rule['name'];
if (!isset($rule['type'])) {
$rule['type'] = 'string';
}
$type = isset($typeMaps[$rule['type']]) ? $typeMaps[$rule['type']] : $rule['type'];
$require = isset($rule['require']) && $rule['require'] ? '<font color="red">必须</font>' : '可选';
$default = isset($rule['default']) ? $rule['default'] : '';
if ($default === NULL) {
$default = 'NULL';
} else if (is_array($default)) {
// @dogstar 20190120 默认值,反序列
$ruleFormat = !empty($rule['format']) ? strtolower($rule['format']) : '';
if ($ruleFormat == 'explode') {
$default = implode(isset($rule['separator']) ? $rule['separator'] : ',', $default);
} else {
$default = json_encode($default);
}
} else if (!is_string($default)) {
$default = var_export($default, true);
}
$other = array();
if (isset($rule['min'])) {
$other[] = '最小:' . $rule['min'];
}
if (isset($rule['max'])) {
$other[] = '最大:' . $rule['max'];
}
if (isset($rule['range'])) {
$other[] = '范围:' . implode('/', $rule['range']);
}
if (isset($rule['source'])) {
$other[] = '数据源:' . strtoupper($rule['source']);
}
$other = implode('', $other);
$desc = isset($rule['desc']) ? trim($rule['desc']) : '';
echo "<tr><td>$name</td><td>$type</td><td>$require</td><td>$default</td><td>$other</td><td>$desc</td></tr>\n";
}
/**
* 返回结果
*/
echo <<<EOT
</tbody>
</table>
<h3><i class="sign out alternate icon"></i>返回结果</h3>
<table class="ui green celled striped table" >
<thead>
<tr><th>返回字段</th><th>类型</th><th>说明</th></tr>
</thead>
<tbody>
EOT;
foreach ($returns as $item) {
$name = $item[1];
$type = isset($typeMaps[$item[0]]) ? $typeMaps[$item[0]] : $item[0];
$detail = $item[2];
echo "<tr><td>$name</td><td>$type</td><td>$detail</td></tr>";
}
echo <<<EOT
</tbody>
</table>
EOT;
/**
* 异常情况
*/
if (!empty($exceptions)) {
echo <<<EOT
<h3><i class="bell icon"></i>异常情况</h3>
<table class="ui red celled striped table" >
<thead>
<tr><th>错误码</th><th>错误描述信息</th>
</thead>
<tbody>
EOT;
foreach ($exceptions as $exItem) {
$exCode = $exItem[0];
$exMsg = isset($exItem[1]) ? $exItem[1] : '';
echo "<tr><td>$exCode</td><td>$exMsg</td></tr>";
}
echo <<<EOT
</tbody>
</table>
EOT;
}
/**
* 返回结果
*/
echo <<<EOT
<h3>
<i class="bug icon"></i>在线测试 &nbsp;&nbsp;
</h3>
EOT;
echo <<<EOT
<table class="ui green celled striped table" >
<thead>
<tr><th width="25%">参数</th><th width="10%">是否必填</th><th width="65%"></th></tr>
</thead>
<tbody id="params">
<tr>
<td>service</td>
<td><font color="red">必须</font></td>
<td><div class="ui fluid input disabled"><input name="service" data-source="get" value="{$service}" style="width:100%;" class="C_input" /></div></td>
</tr>
EOT;
foreach ($rules as $key => $rule){
$source = isset($rule['source']) ? $rule['source'] : '';
//数据源为server和header时该参数不需要提供
if ($source == 'server' || $source == 'header') {
continue;
}
$name = $rule['name'];
$require = isset($rule['require']) && $rule['require'] ? '<font color="red">必须</font>' : '可选';
// 提供给表单的默认值
$default = isset($rule['default'])
? (is_array($rule['default']) // 针对数组,进行反序列化
? (!empty($rule['format']) && $rule['format'] == 'explode'
? implode(isset($rule['separator']) ? $rule['separator'] : ',', $rule['default'])
: json_encode($rule['default']))
: $rule['default'])
: '';
$default = htmlspecialchars($default);
$desc = isset($rule['desc']) ? htmlspecialchars(trim($rule['desc'])) : '';
$inputType = (isset($rule['type']) && $rule['type'] == 'file') ? 'file' : 'text';
$multiple = '';
if ($inputType == 'file') {
$multiple = 'multiple="multiple"';
}
echo <<<EOT
<tr>
<td>{$name}</td>
<td>{$require}</td>
<td><div class="ui fluid input"><input name="{$name}" value="{$default}" data-source="{$source}" placeholder="{$desc}" style="width:100%;" class="C_input" type="$inputType" $multiple/></div></td>
</tr>
EOT;
}
echo <<<EOT
</tbody>
</table>
<div style="display: flex;align-items:center;">
<!--<select name="request_type" style="font-size: 14px; padding: 2px;">
<option value="POST">POST</option>
<option value="GET">GET</option>
</select>-->
EOT;
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) ? 'https://' : 'http://';
$url = $url . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost');
$url .= trim(substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/') + 1), '.');
echo <<<EOT
<!--
接口链接:&nbsp;<input name="request_url" value="{$url}" style="width:500px; height:24px; line-height:18px; font-size:13px;position:relative; padding-left:5px;margin-left: 10px"/>
<input type="submit" name="submit" value="发送" id="submit" style="font-size:14px;line-height: 20px;margin-left: 10px " class="ui green button" />
-->
</div>
<div class="ui fluid action input">
<input placeholder="请求的接口链接" type="text" name="request_url" value="{$url}" >
<button class="ui button green" id="submit" >请求当前接口</button>
</div>
EOT;
/**
* JSON结果
*/
echo <<<EOT
<div class="ui blue message" id="json_output">
</div>
EOT;
/**
* 动态生成客户端代码示例
*/
echo <<<EOT
<h3><i class="code icon"></i>接口返回示例</h3>
EOT;
$demoCodes = '';
$codeFile = API_ROOT . '/src/view/docs/demos/' . $service . '.json';
if (file_exists($codeFile)) {
$demoCodes = htmlspecialchars(file_get_contents($codeFile));
} else {
$demoCodes = '暂时无返回示例,可添加示例文件:' . (\PhalApi\DI()->debug ? $codeFile : $service . '.json');
}
echo <<<EOT
<!-- 代码高亮 -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<div class="ui text">
<pre><code>{$demoCodes}<code></pre>
</div>
EOT;
/**
* 底部
*/
$version = PHALAPI_VERSION;
$thisYear = date('Y');
echo <<<EOT
<div class="ui blue message">
<strong>温馨提示:</strong> 此接口文档是根据接口代码和注释实时自动生成,帮助文档请见<a href="http://docs.phalapi.net/#/v2.0/api-docs" target="_blank">PhalApi 2.x 开发文档</a>
</div>
</div>
</div>
<script type="text/javascript">
function getData() {
var data = new FormData();
var param = [];
$("td input").each(function(index,e) {
if ($.trim(e.value)){
if (e.type != 'file'){
if ($(e).data('source') == 'get') {
param.push(e.name + '=' + e.value);
} else {
data.append(e.name, e.value);
}
if (e.name != "service") $.cookie(e.name, e.value, {expires: 30});
} else{
var files = e.files;
if (files.length == 1){
data.append(e.name, files[0]);
} else{
for (var i = 0; i < files.length; i++) {
data.append(e.name + '[]', files[i]);
}
}
}
}
});
param = param.join('&');
return {param:param, data:data};
}
$(function(){
$("#json_output").hide();
$("#submit").on("click",function(){
var data = getData();
var url_arr = $("input[name=request_url]").val().split('?');
var url = url_arr.shift();
var param = url_arr.join('?');
param = param.length > 0 ? param + '&' + data.param : data.param;
url = url + '?' + param;
$.ajax({
url: url,
type:'post',
data:data.data,
cache: false,
processData: false,
contentType: false,
success:function(res,status,xhr){
console.log(xhr);
var statu = xhr.status + ' ' + xhr.statusText;
var header = xhr.getAllResponseHeaders();
var json_text = JSON.stringify(res, null, 4); // 缩进4个空格
$("#json_output").html('<pre>' + statu + '<br/>' + header + '<br/>' + json_text + '</pre>');
$("#json_output").show();
},
error:function(error){
console.log(error)
}
})
})
fillHistoryData();
checkLastestVersion();
})
// 填充历史数据
function fillHistoryData() {
$("td input").each(function(index,e) {
//ys9n9uvps9aqu
var cookie_value = $.cookie(e.name);
if (e.name != "service" && cookie_value != "" && cookie_value !== undefined) {
e.value = cookie_value;
}
});
}
// 检测最新版本
function checkLastestVersion() {
$.ajax({
url:'https://www.phalapi.net/check_lastest_version.php',
type:'get',
data:{version : '$version'},
success:function(res,status,xhr){
if (!res.ret || res.ret != 200) {
return;
}
if (res.data.need_upgrade >= 0) {
return;
}
$('#version_update').html('&nbsp; | &nbsp; <a target="_blank" href=" ' + res.data.url + ' "><strong>免费升级到 PhalApi ' + res.data.version + '</strong></a>');
},
error:function(error){
console.log(error)
}
})
}
</script>
</body>
</html>
EOT;

View File

@ -0,0 +1,211 @@
<?php
$table_color_arr = explode(" ", "red orange yellow olive teal blue violet purple pink grey black");
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?php echo $projectName; ?> - 在线接口列表</title>
<!-- <link href="https://lib.baomitu.com/semantic-ui/2.3.3/semantic.min.css" rel="stylesheet"> -->
<link rel="stylesheet" href="https://staticfile.qnssl.com/semantic-ui/2.1.6/semantic.min.css">
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<script src="https://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script>
<script src="https://lib.baomitu.com/semantic-ui/2.3.3/semantic.min.js"></script>
<meta name="robots" content="none"/>
</head>
<body>
<div class="row" style="margin-top: 60px;" ></div>
<div class="ui text container" style="max-width: none !important; width: 1200px" id="menu_top">
<div class="ui floating message">
<?php
if (!empty($errorMessage)) {
echo '<div class="ui error message">
<strong>错误:' . $errorMessage . '</strong>
</div>';
}
?>
<div class="ui grid container" style="max-width: none !important;">
<?php
if ($theme == 'fold') {
?>
<div class="four wide column">
<div class="ui vertical accordion menu">
<?php
// 总接口数量
$methodTotal = 0;
foreach ($allApiS as $namespace => $subAllApiS) {
foreach ($subAllApiS as $item) {
$methodTotal += count($item['methods']);
}
}
?>
<div class="item"><h4>接口服务列表&nbsp;(<?php echo $methodTotal; ?>)</h4></div>
<?php
$num = 0;
foreach ($allApiS as $namespace => $subAllApiS) {
echo '<div class="item">';
$subMethodTotal = 0;
foreach ($subAllApiS as $item) {
$subMethodTotal += count($item['methods']);
}
echo sprintf('<h4 class="title active ys9n9uvps9aqu" style="font-size:16px;margin:0px;"><i class="dropdown icon"></i>%s (%d)</h4>', $namespace, $subMethodTotal);
echo sprintf('<div class="content %s" style="margin-left:-16px;margin-right:-16px;margin-bottom:-13px;">', $num == 0 ? 'active' : '');
// 每个命名空间下的接口类
foreach ($subAllApiS as $key => $item) {
echo sprintf('<a class="item %s" data-tab="%s">%s</a>', $num == 0 ? 'active' : '', str_replace('\\', '_', $namespace) . $key, $item['title']);
$num++;
}
echo '</div></div><!-- END OF NAMESPACE -->';
} // 每个命名空间下的接口
?>
<div class="item">
<div class="content" style="margin:-13px -16px;">
<a class="item" href="#menu_top">返回顶部↑↑↑</a>
</div>
</div>
</div>
</div>
<?php } ?> <!-- 折叠时的菜单 -->
<!-- 折叠时与展开时的布局差异 -->
<?php if ($theme == 'fold') { ?>
<div class="twelve wide stretched column">
<?php } else { ?>
<div class="wide stretched column">
<?php
// 展开时,将全部的接口服务,转到第一组
$mergeAllApiS = array('all' => array('methods' => array()));
foreach ($allApiS as $namespace => $subAllApiS) {
foreach ($subAllApiS as $key => $item) {
if (!isset($item['methods']) || !is_array($item['methods'])) {
continue;
}
foreach ($item['methods'] as $mKey => $mItem) {
// 根据搜索关键字,匹配接口名称、功能说明、具体描述 - START
if (!empty($_GET['keyword'])) {
$keyword = $_GET['keyword'];
$isMatchByKeyword = false;
if (stripos($mItem['service'], $keyword) !== false) {
$isMatchByKeyword = true;
} else if (stripos($mItem['title'], $keyword) !== false) {
$isMatchByKeyword = true;
} else if (stripos($mItem['desc'], $keyword) !== false) {
$isMatchByKeyword = true;
}
// 未匹配,则跳过
if (!$isMatchByKeyword) {
continue;
}
}
// 根据搜索关键字,匹配接口名称、功能说明、具体描述 - END
$mergeAllApiS['all']['methods'][$mKey] = $mItem;
}
}
}
$allApiS = array('ALL' => $mergeAllApiS);
}
?>
<?php
$num2 = 0;
foreach ($allApiS as $namespace => $subAllApiS) {
foreach ($subAllApiS as $key => $item) {
?>
<div class="ui tab <?php if ($num2 == 0) { ?>active<?php } ?>" data-tab="<?php echo str_replace('\\', '_', $namespace) . $key; ?>">
<table
class="ui red celled striped table <?php echo $table_color_arr[$num2 % count($table_color_arr)]; ?> celled striped table">
<thead>
<tr>
<th>#</th>
<th>接口服务</th>
<th>接口名称</th>
<th>更多说明</th>
</tr>
</thead>
<tbody>
<?php
$num = 1;
foreach ($item['methods'] as $mKey => $mItem) {
$link = $this->makeApiServiceLink($mItem['service'],$theme);
$NO = $num++;
echo "<tr><td>{$NO}</td><td><a href=\"$link\" target='_blank'>{$mItem['service']}</a></td><td>{$mItem['title']}</td><td>{$mItem['desc']}</td></tr>";
}
?>
</tbody>
</table>
<!-- 主题切换,仅当在线时才支持 -->
<?php
$this->makeThemeButton($theme);
?>
</div>
<?php
$num2++;
} // 单个命名空间的循环
} // 遍历全部命名空间
?>
</div>
</div>
<div class="ui blue message">
<strong>温馨提示:</strong> 此接口服务列表根据后台代码自动生成,可在接口类的文件注释的第一行修改左侧菜单标题。
</div>
</div>
</div>
<script type="text/javascript">
$('.accordion.menu a.item').tab({'deactivate':'all'});
$('.ui.sticky').sticky();
//当点击跳转链接后,回到页面顶部位置
$(".accordion.menu a.item").click(function() {
$('body,html').animate({
scrollTop: 0
},
500);
return false;
});
$('.ui.accordion').accordion({'exclusive':false});
checkLastestVersion();
// 检测最新版本
function checkLastestVersion() {
var version = '<?php echo PHALAPI_VERSION; ?>';
$.ajax({
url:'https://www.phalapi.net/check_lastest_version.php',
type:'get',
data:{version : version},
success:function(res,status,xhr){
console.log(res);
if (!res.ret || res.ret != 200) {
return;
}
if (res.data.need_upgrade >= 0) {
return;
}
$('#version_update').html('&nbsp; | &nbsp; <a target="_blank" href=" ' + res.data.url + ' "><strong>免费升级到 PhalApi ' + res.data.version + '</strong></a>');
},
error:function(error){
console.log(error)
}
})
}
</script>
</body>
</html>

View File

@ -0,0 +1,9 @@
{
"ret": 200,
"data": {
"title": "Hello PhalApi",
"version": "2.7.0",
"time": 1558489902
},
"msg": ""
}

7
web/PhalApi/vendor/autoload.php vendored Normal file
View File

@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit6835957bc29912b8a4cd2dd758af2e80::getLoader();

View File

@ -0,0 +1,445 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

19
web/PhalApi/vendor/composer/LICENSE vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) Nils Adermann, Jordi Boggiano
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.

View File

@ -0,0 +1,9 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@ -0,0 +1,13 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'b0655c4b47b25ec49f0e931fe41ab7a3' => $vendorDir . '/phalapi/kernal/src/bootstrap.php',
'5cab427b0519bb4ddb2f894b03d1d957' => $vendorDir . '/phalapi/kernal/src/functions.php',
'dee36c56d6bb319b2a744b267373bb4b' => $baseDir . '/src/app/functions.php',
'7fc6392d10b5de42d7ff0009e32eda5f' => $baseDir . '/src/app/redis.php',
);

View File

@ -0,0 +1,10 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Qiniu' => array($vendorDir . '/qiniu/qiniu/lib'),
);

View File

@ -0,0 +1,18 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'PhalApi\\Task\\' => array($vendorDir . '/phalapi/task/src'),
'PhalApi\\QrCode\\' => array($vendorDir . '/phalapi/qrcode/src'),
'PhalApi\\Qiniu\\' => array($vendorDir . '/phalapi/qiniu/src'),
'PhalApi\\PHPMailer\\' => array($vendorDir . '/phalapi/phpmailer/src'),
'PhalApi\\NotORM\\' => array($vendorDir . '/phalapi/notorm/src'),
'PhalApi\\CLI\\' => array($vendorDir . '/phalapi/cli/src'),
'PhalApi\\' => array($vendorDir . '/phalapi/kernal/src'),
'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'),
'App\\' => array($baseDir . '/src/app'),
);

View File

@ -0,0 +1,70 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit6835957bc29912b8a4cd2dd758af2e80
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit6835957bc29912b8a4cd2dd758af2e80', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit6835957bc29912b8a4cd2dd758af2e80', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit6835957bc29912b8a4cd2dd758af2e80::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit6835957bc29912b8a4cd2dd758af2e80::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire6835957bc29912b8a4cd2dd758af2e80($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire6835957bc29912b8a4cd2dd758af2e80($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@ -0,0 +1,92 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit6835957bc29912b8a4cd2dd758af2e80
{
public static $files = array (
'b0655c4b47b25ec49f0e931fe41ab7a3' => __DIR__ . '/..' . '/phalapi/kernal/src/bootstrap.php',
'5cab427b0519bb4ddb2f894b03d1d957' => __DIR__ . '/..' . '/phalapi/kernal/src/functions.php',
'dee36c56d6bb319b2a744b267373bb4b' => __DIR__ . '/../..' . '/src/app/functions.php',
'7fc6392d10b5de42d7ff0009e32eda5f' => __DIR__ . '/../..' . '/src/app/redis.php',
);
public static $prefixLengthsPsr4 = array (
'P' =>
array (
'PhalApi\\Task\\' => 13,
'PhalApi\\QrCode\\' => 15,
'PhalApi\\Qiniu\\' => 14,
'PhalApi\\PHPMailer\\' => 18,
'PhalApi\\NotORM\\' => 15,
'PhalApi\\CLI\\' => 12,
'PhalApi\\' => 8,
'PHPMailer\\PHPMailer\\' => 20,
),
'A' =>
array (
'App\\' => 4,
),
);
public static $prefixDirsPsr4 = array (
'PhalApi\\Task\\' =>
array (
0 => __DIR__ . '/..' . '/phalapi/task/src',
),
'PhalApi\\QrCode\\' =>
array (
0 => __DIR__ . '/..' . '/phalapi/qrcode/src',
),
'PhalApi\\Qiniu\\' =>
array (
0 => __DIR__ . '/..' . '/phalapi/qiniu/src',
),
'PhalApi\\PHPMailer\\' =>
array (
0 => __DIR__ . '/..' . '/phalapi/phpmailer/src',
),
'PhalApi\\NotORM\\' =>
array (
0 => __DIR__ . '/..' . '/phalapi/notorm/src',
),
'PhalApi\\CLI\\' =>
array (
0 => __DIR__ . '/..' . '/phalapi/cli/src',
),
'PhalApi\\' =>
array (
0 => __DIR__ . '/..' . '/phalapi/kernal/src',
),
'PHPMailer\\PHPMailer\\' =>
array (
0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src',
),
'App\\' =>
array (
0 => __DIR__ . '/../..' . '/src/app',
),
);
public static $prefixesPsr0 = array (
'Q' =>
array (
'Qiniu' =>
array (
0 => __DIR__ . '/..' . '/qiniu/qiniu/lib',
),
),
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit6835957bc29912b8a4cd2dd758af2e80::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit6835957bc29912b8a4cd2dd758af2e80::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit6835957bc29912b8a4cd2dd758af2e80::$prefixesPsr0;
}, null, ClassLoader::class);
}
}

View File

@ -0,0 +1,442 @@
[
{
"name": "phalapi/cli",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/phalapi/cli.git",
"reference": "c5df41e5fa483ad5990296421cde808a0d29f36f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phalapi/cli/zipball/c5df41e5fa483ad5990296421cde808a0d29f36f",
"reference": "c5df41e5fa483ad5990296421cde808a0d29f36f",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2019-03-30T15:41:41+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"PhalApi\\CLI\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0+"
],
"authors": [
{
"name": "Dogstar Huang",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar",
"role": "Developer"
}
],
"description": "PhalApi 2.x 扩展类库 - CLI命令行可用于开发命令行应用基于GetOpt主要作用是将命令参数进行解析和处理。",
"homepage": "https://www.phalapi.net/",
"keywords": [
"cli",
"phalapi",
"phalapi-cli"
]
},
{
"name": "phalapi/kernal",
"version": "2.7.0",
"version_normalized": "2.7.0.0",
"source": {
"type": "git",
"url": "https://github.com/phalapi/kernal.git",
"reference": "27eb88404a0c47a3165a5149d2e9b5e61c3f2465"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phalapi/kernal/zipball/27eb88404a0c47a3165a5149d2e9b5e61c3f2465",
"reference": "27eb88404a0c47a3165a5149d2e9b5e61c3f2465",
"shasum": ""
},
"require": {
"phalapi/notorm": "2.*.*",
"php": ">=5.3.3"
},
"time": "2019-06-21T04:56:41+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"src/bootstrap.php",
"src/functions.php"
],
"psr-4": {
"PhalApi\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0+"
],
"authors": [
{
"name": "Dogstar Huang",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar",
"role": "Developer"
},
{
"name": "kwan",
"email": "303198069@qq.com",
"role": "Developer"
}
],
"description": "PhalApi 2.x 框架核心部分。",
"homepage": "https://www.phalapi.net/",
"keywords": [
"api",
"framework",
"phalapi"
]
},
{
"name": "phalapi/notorm",
"version": "2.7.0",
"version_normalized": "2.7.0.0",
"source": {
"type": "git",
"url": "https://github.com/phalapi/notorm.git",
"reference": "b91a22be688626521fd235d2e32849de0399e42e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phalapi/notorm/zipball/b91a22be688626521fd235d2e32849de0399e42e",
"reference": "b91a22be688626521fd235d2e32849de0399e42e",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2019-05-23T04:49:49+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"PhalApi\\NotORM\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0+"
],
"authors": [
{
"name": "Dogstar Huang",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar",
"role": "Developer"
}
],
"description": "基于NotORM类库的优化版本专门用于PhalApi 2.x 开源接口框架。",
"homepage": "http://www.phalapi.net",
"keywords": [
"api",
"notorm",
"phalapi"
]
},
{
"name": "phalapi/phpmailer",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/phalapi/PHPMailer.git",
"reference": "7c875aeb572e18a0e667a5fc792926ab1d2403fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phalapi/PHPMailer/zipball/7c875aeb572e18a0e667a5fc792926ab1d2403fc",
"reference": "7c875aeb572e18a0e667a5fc792926ab1d2403fc",
"shasum": ""
},
"require": {
"phpmailer/phpmailer": "~6.0"
},
"time": "2019-05-15T09:35:20+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"PhalApi\\PHPMailer\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0+"
],
"authors": [
{
"name": "Dogstar Huang",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar",
"role": "Developer"
}
],
"description": "PhalApi 2.x扩展类库基于PHPMailer的邮件发送。",
"homepage": "https://www.phalapi.net/",
"keywords": [
"phalapi",
"phalapi-phpmailer",
"phpmailer"
]
},
{
"name": "phalapi/qiniu",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/phalapi/qiniu.git",
"reference": "91592b86317441a47ec067c16e149a7e10ca9a5f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phalapi/qiniu/zipball/91592b86317441a47ec067c16e149a7e10ca9a5f",
"reference": "91592b86317441a47ec067c16e149a7e10ca9a5f",
"shasum": ""
},
"require": {
"qiniu/qiniu": "*"
},
"time": "2019-06-26T13:39:56+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"PhalApi\\Qiniu\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0+"
],
"authors": [
{
"name": "Dogstar Huang",
"role": "Developer",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar"
}
],
"description": "PhalApi 2.x 扩展类库:七牛云存储接口调用",
"homepage": "https://www.phalapi.net/",
"keywords": [
"phalapi",
"phalapi-qiniu",
"qiniu"
]
},
{
"name": "phalapi/qrcode",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/phalapi/qrcode.git",
"reference": "cbb3c5f3f95a7902b0a72786a77495ada0c006b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phalapi/qrcode/zipball/cbb3c5f3f95a7902b0a72786a77495ada0c006b7",
"reference": "cbb3c5f3f95a7902b0a72786a77495ada0c006b7",
"shasum": ""
},
"time": "2017-12-29T12:03:03+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"PhalApi\\QrCode\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0+"
],
"authors": [
{
"name": "dogstar huang",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar",
"role": "Developer"
}
],
"description": "PhalApi 2.x 扩展类库基于QRCode实现的二维码扩展",
"homepage": "https://www.phalapi.net/",
"keywords": [
"phalapi",
"phalapi-qrcode",
"qrcode",
"二维码"
]
},
{
"name": "phalapi/task",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/phalapi/task.git",
"reference": "552421219a3097a81c576fc2607d96894d489def"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phalapi/task/zipball/552421219a3097a81c576fc2607d96894d489def",
"reference": "552421219a3097a81c576fc2607d96894d489def",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2018-04-24T14:25:40+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-4": {
"PhalApi\\Task\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0+"
],
"authors": [
{
"name": "Dogstar Huang",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar",
"role": "Developer"
}
],
"description": "PhalApi 2.x 扩展类库 - Task计划任务以接口服务形式实现的新型计划任务。",
"homepage": "https://www.phalapi.net/",
"keywords": [
"phalapi",
"phalapi-task",
"task"
]
},
{
"name": "phpmailer/phpmailer",
"version": "6.0.x-dev",
"version_normalized": "6.0.9999999.9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "ea25dc122d22966b7dd4ca1083c63afeeb50dfcd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/ea25dc122d22966b7dd4ca1083c63afeeb50dfcd",
"reference": "ea25dc122d22966b7dd4ca1083c63afeeb50dfcd",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"php": ">=5.5.0"
},
"require-dev": {
"doctrine/annotations": "1.2.*",
"phpdocumentor/phpdocumentor": "2.*",
"phpunit/phpunit": "4.*",
"zendframework/zend-eventmanager": "3.0.*",
"zendframework/zend-i18n": "2.7.3",
"zendframework/zend-serializer": "2.7.*"
},
"suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
},
"time": "2017-08-28T11:42:41+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"PHPMailer\\PHPMailer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Jim Jagielski",
"email": "jimjag@gmail.com"
},
{
"name": "Marcus Bointon",
"email": "phpmailer@synchromedia.co.uk"
},
{
"name": "Andy Prevost",
"email": "codeworxtech@users.sourceforge.net"
},
{
"name": "Brent R. Matzelle"
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP"
},
{
"name": "qiniu/qiniu",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/hfcorriez/php-qiniu.git",
"reference": "6b43b5020ec78b4cb68fb337ae8937c1679d5aef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/hfcorriez/php-qiniu/zipball/6b43b5020ec78b4cb68fb337ae8937c1679d5aef",
"reference": "6b43b5020ec78b4cb68fb337ae8937c1679d5aef",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"time": "2016-04-14T15:38:21+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Qiniu": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Corrie Zhao",
"email": "hfcorriez@gmail.com"
}
],
"description": "Qiniu SDK",
"keywords": [
"api",
"cloud storage",
"qiniu",
"sdk"
]
}
]

661
web/PhalApi/vendor/phalapi/cli/LICENSE vendored Normal file
View File

@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

View File

@ -0,0 +1,52 @@
# CLI扩展类库
此类库可用于开发命令行应用基于GetOpt主要作用是将命令参数进行解析和处理。
## 安装
在项目的composer.json文件中添加
```
{
"require": {
"phalapi/cli": "dev-master"
}
}
```
配置好后执行composer update更新操作即可。
## 编写命令行入口文件
参考原来的入口文件index.php编写以下的CLI入口文件保存到./public/cli 文件:
```
#!/usr/bin/env php
<?php
require_once dirname(__FILE__) . '/init.php';
$cli = new PhalApi\CLI\Lite();
$cli->response();
```
## 运行和使用
### (1)正常运行
默认接口服务使用```service```名称,缩写为```s```,如运行命令:
```
$ ./cli -s Site.Index --username dogstar
{"ret":200,"data":{"title":"Hello PhalApi","version":"2.0.1","time":1501079142},"msg":""}
```
### (2) 获取帮助
指定接口服务service后即可使用 --help 参数以查看接口帮助信息,如:
```
$ ./cli -s Examples_CURD.Get --help
Usage: ./cli [options] [operands]
Options:
-s, --service <arg> 接口服务
-h, --help 查看帮助信息
--id <arg> ID
```
### (3) 异常情况
异常时,将显示异常错误提示信息,以及帮助信息。

View File

@ -0,0 +1,26 @@
{
"name": "phalapi/cli",
"description": "PhalApi 2.x 扩展类库 - CLI命令行可用于开发命令行应用基于GetOpt主要作用是将命令参数进行解析和处理。",
"keywords": [
"phalapi", "phalapi-cli", "cli"
],
"license": "GPL-3.0+",
"homepage": "https://www.phalapi.net/",
"type": "library",
"authors": [
{
"name": "dogstar huang",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar",
"role": "Developer"
}
],
"require": {
"php": ">=5.3.3"
},
"autoload": {
"psr-4": {
"PhalApi\\CLI\\": "src"
}
}
}

View File

@ -0,0 +1,119 @@
<?php
namespace PhalApi\CLI;
/**
* 用于开发命令行应用的扩展类库
*
* - Example
```
$cli = new PhalApi\CLI\Lite();
$cli->response();
```
*
* - Usage
```
./cli -s Site.Index --username dogstar
```
*
* @author dogstar <chanzonghuang@gmail.com> 20170205
*/
require_once dirname(__FILE__) . '/Ulrichsg/Getopt/Getopt.php';
require_once dirname(__FILE__) . '/Ulrichsg/Getopt/Option.php';
require_once dirname(__FILE__) . '/Ulrichsg/Getopt/Argument.php';
require_once dirname(__FILE__) . '/Ulrichsg/Getopt/CommandLineParser.php';
require_once dirname(__FILE__) . '/Ulrichsg/Getopt/OptionParser.php';
use Ulrichsg\Getopt\Getopt;
use Ulrichsg\Getopt\Option;
use Ulrichsg\Getopt\Argument;
use PhalApi\PhalApi;
use PhalApi\Request;
use PhalApi\ApiFactory;
use PhalApi\Exception;
class Lite {
public function response() {
// 解析获取service参数
$serviceOpt = new Option('s', 'service', Getopt::REQUIRED_ARGUMENT);
$serviceOpt->setDescription('接口服务');
$helpOpt = new Option('h', 'help');
$helpOpt->setDescription('查看帮助信息');
$getopt = new Getopt(array(
$serviceOpt,
$helpOpt
));
$service = NULL;
try {
$getopt->parse();
$service = $getopt['service'];
if ($service === NULL) {
echo $getopt->getHelpText();
echo "\n\nError: 缺少service参数\n";
exit(1);
}
} catch (UnexpectedValueException $e) {
// just go ahead ...
}
// 再转换处理 。。。
try{
// 获取接口实例
$rules = array();
try {
\PhalApi\DI()->request = new Request(array('service' => $service));
$api = ApiFactory::generateService(false);
$rules = $api->getApiRules();
} catch (Exception $ex){
throw new \UnexpectedValueException($ex->getMessage());
}
// PhalApi接口参数转换为命令行参数
$rule2opts = array();
foreach ($rules as $ruleKey => $ruleItem) {
$opt = new Option(null, $ruleItem['name'], !empty($ruleItem['require']) ? Getopt::REQUIRED_ARGUMENT : Getopt::OPTIONAL_ARGUMENT);
if (isset($ruleItem['default'])) {
$opt->setArgument(new Argument($ruleItem['default']));
}
if (isset($ruleItem['desc'])) {
$opt->setDescription($ruleItem['desc']);
}
$rule2opts[] = $opt;
}
// 优化http://qa.phalapi.net/?/question/1499
if (empty($rule2opts)) {
$rule2opts[] = $helpOpt;
}
// 添加参数选项,提取命令行参数并重新注册请求
$getopt->addOptions($rule2opts);
$getopt->parse();
if ($getopt['help']) {
echo $getopt->getHelpText();
exit(1);
}
\PhalApi\DI()->request = new Request($getopt->getOptions());
// 转交PhalApi重新响应处理
$api = new PhalApi();
$rs = $api->response();
$rs->output();
} catch (\UnexpectedValueException $e) {
echo $getopt->getHelpText();
echo "\n\nError: ".$e->getMessage()."\n";
exit(1);
}
}
}

View File

@ -0,0 +1,115 @@
<?php
namespace Ulrichsg\Getopt;
class Argument
{
/** @var string */
private $default;
/** @var callable */
private $validation;
/** @var string */
private $name;
/**
* Creates a new argument.
*
* @param scalar|null $default Default value or NULL
* @param callable|null $validation a validation function (optional)
* @throws \InvalidArgumentException
*/
public function __construct($default = null, $validation = null, $name = "arg")
{
if (!is_null($default)) {
$this->setDefaultValue($default);
}
if (!is_null($validation)) {
$this->setValidation($validation);
}
$this->name = $name;
}
/**
* Set the default value
*
* @param scalar $value
* @return Argument this object (for chaining calls)
* @throws \InvalidArgumentException
*/
public function setDefaultValue($value)
{
if (!is_scalar($value)) {
throw new \InvalidArgumentException("Default value must be scalar");
}
$this->default = $value;
return $this;
}
/**
* Set a validation function.
* The function must take a string and return true if it is valid, false otherwise.
*
* @param callable $callable
* @return Argument this object (for chaining calls)
* @throws \InvalidArgumentException
*/
public function setValidation($callable)
{
if (!is_callable($callable)) {
throw new \InvalidArgumentException("Validation must be a callable");
}
$this->validation = $callable;
return $this;
}
/**
* Check if an argument validates according to the specification.
*
* @param string $arg
* @return bool
*/
public function validates($arg)
{
return (bool)call_user_func($this->validation, $arg);
}
/**
* Check if the argument has a validation function
*
* @return bool
*/
public function hasValidation()
{
return isset($this->validation);
}
/**
* Check whether the argument has a default value
*
* @return boolean
*/
public function hasDefaultValue()
{
return !empty($this->default);
}
/**
* Retrieve the default value
*
* @return scalar|null
*/
public function getDefaultValue()
{
return $this->default;
}
/**
* Retrieve the argument name
*
* @return string
*/
public function getName()
{
return $this->name;
}
}

View File

@ -0,0 +1,240 @@
<?php
namespace Ulrichsg\Getopt;
/**
* Parses command line arguments according to a list of allowed options.
*/
class CommandLineParser
{
/** @var Option[] */
private $optionList;
private $options = array();
private $operands = array();
/**
* Creates a new instance.
*
* @param Option[] $optionList the list of allowed options
*/
public function __construct(array $optionList)
{
$this->optionList = $optionList;
}
/**
* Parses the given arguments and converts them into options and operands.
*
* @param mixed $arguments a string or an array with one argument per element
*/
public function parse($arguments)
{
if (!is_array($arguments)) {
$arguments = explode(' ', $arguments);
}
$operands = array();
$numArgs = count($arguments);
for ($i = 0; $i < $numArgs; ++$i) {
$arg = trim($arguments[$i]);
if (empty($arg)) {
continue;
}
if (($arg === '--') || ($arg === '-') || (mb_substr($arg, 0, 1) !== '-')){
// no more options, treat the remaining arguments as operands
$firstOperandIndex = ($arg == '--') ? $i + 1 : $i;
$operands = array_slice($arguments, $firstOperandIndex);
break;
}
if (mb_substr($arg, 0, 2) == '--') {
$this->addLongOption($arguments, $i);
} else {
$this->addShortOption($arguments, $i);
}
} // endfor
$this->addDefaultValues();
// remove '--' from operands array
foreach ($operands as $operand) {
if ($operand !== '--') {
$this->operands[] = $operand;
}
}
}
/**
* Returns the options created by a previous invocation of parse().
*
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* Returns the operands created by a previous invocation of parse(),
*
* @return array
*/
public function getOperands()
{
return $this->operands;
}
private function addShortOption($arguments, &$i)
{
$numArgs = count($arguments);
$option = mb_substr($arguments[$i], 1);
if (mb_strlen($option) > 1) {
// multiple options strung together
$options = $this->splitString($option, 1);
foreach ($options as $j => $ch) {
// If a required argument is encountered, treat the rest of the
// string (or the next argument, if it's the last character) as
// its value
if ($this->optionHasArgument($ch)) {
if ($j < count($options) - 1) {
// Required argument in the middle of the string, treat
// the remainder as the argument; e.g. `ssh -vvvp222`
$value = implode('', array_slice($options, $j + 1));
$this->addOption($ch, $value);
} else {
// Required argument was last, e.g. `ssh -vvvp 222`
$value = isset($arguments[$i + 1]) ? $arguments[$i + 1] : null;
$this->addOption($ch, $value);
}
break;
} else {
$this->addOption($ch, null);
}
}
} else {
if ($i < $numArgs - 1
&& ((mb_substr($arguments[$i + 1], 0, 1) !== '-') || ($arguments[$i + 1] === '-'))
&& $this->optionHasArgument($option)
) {
$value = $arguments[$i + 1];
++$i;
} else {
$value = null;
}
$this->addOption($option, $value);
}
}
private function addLongOption($arguments, &$i)
{
$option = mb_substr($arguments[$i], 2);
if (strpos($option, '=') === false) {
if ($i < count($arguments) - 1
&& ((mb_substr($arguments[$i + 1], 0, 1) !== '-') || ($arguments[$i + 1] === '-'))
&& $this->optionHasArgument($option)
) {
$value = $arguments[$i + 1];
++$i;
} else {
$value = null;
}
} else {
list($option, $value) = explode('=', $option, 2);
}
$this->addOption($option, $value);
}
/**
* Add an option to the list of known options.
*
* @param string $string the option's name
* @param string $value the option's value (or null)
* @throws \UnexpectedValueException
* @return void
*/
private function addOption($string, $value)
{
foreach ($this->optionList as $option) {
if ($option->matches($string)) {
if ($option->mode() == Getopt::REQUIRED_ARGUMENT && !mb_strlen($value)) {
throw new \UnexpectedValueException("Option '$string' must have a value");
}
if ($option->getArgument()->hasValidation()) {
if ((mb_strlen($value) > 0) && !$option->getArgument()->validates($value)) {
throw new \UnexpectedValueException("Option '$string' has an invalid value");
}
}
// for no-argument options, check if they are duplicate
if ($option->mode() == Getopt::NO_ARGUMENT) {
$oldValue = isset($this->options[$string]) ? $this->options[$string] : null;
$value = is_null($oldValue) ? 1 : $oldValue + 1;
}
// for optional-argument options, set value to 1 if none was given
$value = (mb_strlen($value) > 0) ? $value : 1;
// add both long and short names (if they exist) to the option array to facilitate lookup
if ($option->short()) {
$this->options[$option->short()] = $value;
}
if ($option->long()) {
$this->options[$option->long()] = $value;
}
return;
}
}
// @dogstar 允许有更多无关的参数
// throw new \UnexpectedValueException("Option '$string' is unknown");
}
/**
* If there are options with default values that were not overridden by the parsed option string,
* add them to the list of known options.
*/
private function addDefaultValues()
{
foreach ($this->optionList as $option) {
if ($option->getArgument()->hasDefaultValue()
&& !isset($this->options[$option->short()])
&& !isset($this->options[$option->long()])
) {
if ($option->short()) {
$this->addOption($option->short(), $option->getArgument()->getDefaultValue());
}
if ($option->long()) {
$this->addOption($option->long(), $option->getArgument()->getDefaultValue());
}
}
}
}
/**
* Return true if the given option can take an argument, false if it can't or is unknown.
*
* @param string $name the option's name
* @return boolean
*/
private function optionHasArgument($name)
{
foreach ($this->optionList as $option) {
if ($option->matches($name)) {
return $option->mode() != Getopt::NO_ARGUMENT;
}
}
return false;
}
/**
* Split the string into individual characters,
*
* @param string $string string to split
* @return array
*/
private function splitString($string)
{
$result = array();
for ($i = 0; $i < mb_strlen($string, "UTF-8"); ++$i) {
$result[] = mb_substr($string, $i, 1, "UTF-8");
}
return $result;
}
}

View File

@ -0,0 +1,295 @@
<?php
namespace Ulrichsg\Getopt;
/**
* Getopt.PHP allows for easy processing of command-line arguments.
* It is a more powerful, object-oriented alternative to PHP's built-in getopt() function.
*
* @version 2.1.0
* @license MIT
* @link http://ulrichsg.github.io/getopt-php
*/
class Getopt implements \Countable, \ArrayAccess, \IteratorAggregate
{
const NO_ARGUMENT = 0;
const REQUIRED_ARGUMENT = 1;
const OPTIONAL_ARGUMENT = 2;
/** @var OptionParser */
private $optionParser;
/** @var string */
private $scriptName;
/** @var Option[] */
private $optionList = array();
/** @var array */
private $options = array();
/** @var array */
private $operands = array();
/** @var string */
private $banner = "Usage: %s [options] [operands]\n";
/**
* Creates a new Getopt object.
*
* The argument $options can be either a string in the format accepted by the PHP library
* function getopt() or an array.
*
* @param mixed $options Array of options, a String, or null (see documentation for details)
* @param int $defaultType The default option type to use when omitted (optional)
* @throws \InvalidArgumentException
*
* @link https://www.gnu.org/s/hello/manual/libc/Getopt.html GNU Getopt manual
*/
public function __construct($options = null, $defaultType = Getopt::NO_ARGUMENT)
{
$this->optionParser = new OptionParser($defaultType);
if ($options !== null) {
$this->addOptions($options);
}
}
/**
* Extends the list of known options. Takes the same argument types as the constructor.
*
* @param mixed $options
* @throws \InvalidArgumentException
*/
public function addOptions($options)
{
if (is_string($options)) {
$this->mergeOptions($this->optionParser->parseString($options));
} elseif (is_array($options)) {
$this->mergeOptions($this->optionParser->parseArray($options));
} else {
throw new \InvalidArgumentException("Getopt(): argument must be string or array");
}
}
/**
* Merges new options with the ones already in the Getopt optionList, making sure the resulting list is free of
* conflicts.
*
* @param Option[] $options The list of new options
* @throws \InvalidArgumentException
*/
private function mergeOptions(array $options)
{
/** @var Option[] $mergedList */
$mergedList = array_merge($this->optionList, $options);
$duplicates = array();
foreach ($mergedList as $option) {
foreach ($mergedList as $otherOption) {
if (($option === $otherOption) || in_array($otherOption, $duplicates)) {
continue;
}
if ($this->optionsConflict($option, $otherOption)) {
throw new \InvalidArgumentException('Failed to add options due to conflict');
}
if (($option->short() === $otherOption->short()) && ($option->long() === $otherOption->long())) {
$duplicates[] = $option;
}
}
}
foreach ($mergedList as $index => $option) {
if (in_array($option, $duplicates)) {
unset($mergedList[$index]);
}
}
$this->optionList = array_values($mergedList);
}
private function optionsConflict(Option $option1, Option $option2) {
if ((is_null($option1->short()) && is_null($option2->short()))
|| (is_null($option1->long()) && is_null($option2->long()))) {
return false;
}
return ((($option1->short() === $option2->short()) && ($option1->long() !== $option2->long()))
|| (($option1->short() !== $option2->short()) && ($option1->long() === $option2->long())));
}
/**
* Evaluate the given arguments. These can be passed either as a string or as an array.
* If nothing is passed, the running script's command line arguments are used.
*
* An {@link \UnexpectedValueException} or {@link \InvalidArgumentException} is thrown
* when the arguments are not well-formed or do not conform to the options passed by the user.
*
* @param mixed $arguments optional ARGV array or space separated string
*/
public function parse($arguments = null)
{
$this->options = array();
if (!isset($arguments)) {
global $argv;
$arguments = $argv;
$this->scriptName = array_shift($arguments); // $argv[0] is the script's name
} elseif (is_string($arguments)) {
$this->scriptName = $_SERVER['PHP_SELF'];
$arguments = explode(' ', $arguments);
}
$parser = new CommandLineParser($this->optionList);
$parser->parse($arguments);
$this->options = $parser->getOptions();
$this->operands = $parser->getOperands();
}
/**
* Returns the value of the given option. Must be invoked after parse().
*
* The return value can be any of the following:
* <ul>
* <li><b>null</b> if the option is not given and does not have a default value</li>
* <li><b>the default value</b> if it has been defined and the option is not given</li>
* <li><b>an integer</b> if the option is given without argument. The
* returned value is the number of occurrences of the option.</li>
* <li><b>a string</b> if the option is given with an argument. The returned value is that argument.</li>
* </ul>
*
* @param string $name The (short or long) option name.
* @return mixed
*/
public function getOption($name)
{
return isset($this->options[$name]) ? $this->options[$name] : null;
}
/**
* Returns the list of options. Must be invoked after parse() (otherwise it returns an empty array).
*
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* Returns the list of operands. Must be invoked after parse().
*
* @return array
*/
public function getOperands()
{
return $this->operands;
}
/**
* Returns the i-th operand (starting with 0), or null if it does not exist. Must be invoked after parse().
*
* @param int $i
* @return string
*/
public function getOperand($i)
{
return ($i < count($this->operands)) ? $this->operands[$i] : null;
}
/**
* Returns the banner string
*
* @return string
*/
public function getBanner()
{
return $this->banner;
}
/**
* Set the banner string
*
* @param string $banner The banner string; will be passed to sprintf(), can include %s for current scripts name.
* Be sure to include a trailing line feed.
* @return Getopt
*/
public function setBanner($banner)
{
$this->banner = $banner;
return $this;
}
/**
* Returns an usage information text generated from the given options.
* @param int $padding Number of characters to pad output of options to
* @return string
*/
public function getHelpText($padding = 25)
{
$helpText = sprintf($this->getBanner(), $this->scriptName);
$helpText .= "Options:\n";
foreach ($this->optionList as $option) {
$mode = '';
switch ($option->mode()) {
case self::NO_ARGUMENT:
$mode = '';
break;
case self::REQUIRED_ARGUMENT:
$mode = "<".$option->getArgument()->getName().">";
break;
case self::OPTIONAL_ARGUMENT:
$mode = "[<".$option->getArgument()->getName().">]";
break;
}
$short = ($option->short()) ? '-'.$option->short() : '';
$long = ($option->long()) ? '--'.$option->long() : '';
if ($short && $long) {
$options = $short.', '.$long;
} else {
$options = $short ? : $long;
}
$padded = str_pad(sprintf(" %s %s", $options, $mode), $padding);
$helpText .= sprintf("%s %s\n", $padded, $option->getDescription());
}
return $helpText;
}
/*
* Interface support functions
*/
public function count()
{
return count($this->options);
}
public function offsetExists($offset)
{
return isset($this->options[$offset]);
}
public function offsetGet($offset)
{
return $this->getOption($offset);
}
public function offsetSet($offset, $value)
{
throw new \LogicException('Getopt is read-only');
}
public function offsetUnset($offset)
{
throw new \LogicException('Getopt is read-only');
}
public function getIterator()
{
// For options that have both short and long names, $this->options has two entries.
// We don't want this when iterating, so we have to filter the duplicates out.
$filteredOptions = array();
foreach ($this->options as $name => $value) {
$keep = true;
foreach ($this->optionList as $option) {
if ($option->long() == $name && !is_null($option->short())) {
$keep = false;
}
}
if ($keep) {
$filteredOptions[$name] = $value;
}
}
return new \ArrayIterator($filteredOptions);
}
}

View File

@ -0,0 +1,162 @@
<?php
namespace Ulrichsg\Getopt;
/**
* Represents an option that Getopt accepts.
*/
class Option
{
private $short;
private $long;
private $mode;
private $description = '';
private $argument;
/**
* Creates a new option.
*
* @param string $short the option's short name (a single letter or digit) or null for long-only options
* @param string $long the option's long name (a string of 2+ letter/digit/_/- characters, starting with a letter
* or digit) or null for short-only options
* @param int $mode whether the option can/must have an argument (one of the constants defined in the Getopt class)
* (optional, defaults to no argument)
* @throws \InvalidArgumentException if both short and long name are null
*/
public function __construct($short, $long, $mode = Getopt::NO_ARGUMENT)
{
if (!$short && !$long) {
throw new \InvalidArgumentException("The short and long name may not both be empty");
}
$this->setShort($short);
$this->setLong($long);
$this->setMode($mode);
$this->argument = new Argument();
}
/**
* Defines a description for the option. This is only used for generating usage information.
*
* @param string $description
* @return Option this object (for chaining calls)
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Defines a default value for the option.
*
* @param mixed $value
* @return Option this object (for chaining calls)
*/
public function setDefaultValue($value)
{
$this->argument->setDefaultValue($value);
return $this;
}
/**
* Defines a validation function for the option.
*
* @param callable $function
* @return Option this object (for chaining calls)
*/
public function setValidation($function)
{
$this->argument->setValidation($function);
return $this;
}
/**
* Sets the argument object directly.
*
* @param Argument $arg
* @return Option this object (for chaining calls)
*/
public function setArgument(Argument $arg)
{
if ($this->mode == Getopt::NO_ARGUMENT) {
throw new \InvalidArgumentException("Option should not have any argument");
}
$this->argument = $arg;
return $this;
}
/**
* Returns true if the given string is equal to either the short or the long name.
*
* @param string $string
* @return bool
*/
public function matches($string)
{
return ($string === $this->short) || ($string === $this->long);
}
public function short()
{
return $this->short;
}
public function long()
{
return $this->long;
}
public function mode()
{
return $this->mode;
}
public function getDescription()
{
return $this->description;
}
/**
* Retrieve the argument object
*
* @return Argument
*/
public function getArgument()
{
return $this->argument;
}
/**
* Fluent interface for constructor so options can be added during construction
* @see Options::__construct()
*/
public static function create($short, $long, $mode = Getopt::NO_ARGUMENT)
{
return new self($short, $long, $mode);
}
private function setShort($short)
{
if (!(is_null($short) || preg_match("/^[a-zA-Z0-9]$/", $short))) {
throw new \InvalidArgumentException("Short option must be null or a letter/digit, found '$short'");
}
$this->short = $short;
}
private function setLong($long)
{
if (!(is_null($long) || preg_match("/^[a-zA-Z0-9][a-zA-Z0-9_-]{1,}$/", $long))) {
throw new \InvalidArgumentException("Long option must be null or an alphanumeric string, found '$long'");
}
$this->long = $long;
}
private function setMode($mode)
{
if (!in_array($mode, array(Getopt::NO_ARGUMENT, Getopt::OPTIONAL_ARGUMENT, Getopt::REQUIRED_ARGUMENT), true)) {
throw new \InvalidArgumentException("Option mode must be one of "
."Getopt::NO_ARGUMENT, Getopt::OPTIONAL_ARGUMENT and Getopt::REQUIRED_ARGUMENT");
}
$this->mode = $mode;
}
}

View File

@ -0,0 +1,137 @@
<?php
namespace Ulrichsg\Getopt;
/**
* Converts user-given option specifications into Option objects.
*/
class OptionParser
{
private $defaultMode;
/**
* Creates a new instance.
*
* @param int $defaultMode will be assigned to options when no mode is given for them.
*/
public function __construct($defaultMode) {
$this->defaultMode = $defaultMode;
}
/**
* Parse a GNU-style option string.
*
* @param string $string the option string
* @return Option[]
* @throws \InvalidArgumentException
*/
public function parseString($string)
{
if (!mb_strlen($string)) {
throw new \InvalidArgumentException('Option string must not be empty');
}
$options = array();
$eol = mb_strlen($string) - 1;
$nextCanBeColon = false;
for ($i = 0; $i <= $eol; ++$i) {
$ch = $string[$i];
if (!preg_match('/^[A-Za-z0-9]$/', $ch)) {
$colon = $nextCanBeColon ? " or ':'" : '';
throw new \InvalidArgumentException("Option string is not well formed: "
."expected a letter$colon, found '$ch' at position ".($i + 1));
}
if ($i == $eol || $string[$i + 1] != ':') {
$options[] = new Option($ch, null, Getopt::NO_ARGUMENT);
$nextCanBeColon = true;
} elseif ($i < $eol - 1 && $string[$i + 2] == ':') {
$options[] = new Option($ch, null, Getopt::OPTIONAL_ARGUMENT);
$i += 2;
$nextCanBeColon = false;
} else {
$options[] = new Option($ch, null, Getopt::REQUIRED_ARGUMENT);
++$i;
$nextCanBeColon = true;
}
}
return $options;
}
/**
* Processes an option array. The array elements can either be Option objects or arrays conforming to the format
* (short, long, mode [, description [, default]]). See documentation for details.
*
* Developer note: Please don't add any further elements to the array. Future features should be configured only
* through the Option class's methods.
*
* @param array $array
* @return Option[]
* @throws \InvalidArgumentException
*/
public function parseArray(array $array)
{
if (empty($array)) {
throw new \InvalidArgumentException('No options given');
}
$options = array();
foreach ($array as $row) {
if ($row instanceof Option) {
$options[] = $row;
} elseif (is_array($row)) {
$options[] = $this->createOption($row);
} else {
throw new \InvalidArgumentException("Invalid option type, must be Option or array");
}
}
return $options;
}
/**
* @param array $row
* @return Option
*/
private function createOption(array $row)
{
$rowSize = count($row);
if ($rowSize < 3) {
$row = $this->completeOptionArray($row);
}
$option = new Option($row[0], $row[1], $row[2]);
if ($rowSize >= 4) {
$option->setDescription($row[3]);
}
if ($rowSize >= 5 && $row[2] != Getopt::NO_ARGUMENT) {
$option->setArgument(new Argument($row[4]));
}
return $option;
}
/**
* When using arrays, instead of a full option spec ([short, long, type]) users can leave out one or more of
* these parts and have Getopt fill them in intelligently:
* - If either the short or the long option string is left out, the first element of the given array is interpreted
* as either short (if it has length 1) or long, and the other one is set to null.
* - If the type is left out, it is set to NO_ARGUMENT.
*
* @param array $row
* @return array
*/
private function completeOptionArray(array $row)
{
$short = (strlen($row[0]) == 1) ? $row[0] : null;
$long = null;
if (is_null($short)) {
$long = $row[0];
} elseif (count($row) > 1 && !is_int($row[1])) {
$long = $row[1];
}
$mode = $this->defaultMode;
if (count($row) == 2 && is_int($row[1])) {
$mode = $row[1];
}
return array($short, $long, $mode);
}
}

View File

@ -0,0 +1,9 @@
composer.lock
vendor/
.project
.buildpath
tests/src/Cache/cache
tests/src/Helper/docs
.DS_Store

View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -0,0 +1,9 @@
# PhalApi 2.x 核心框架
[![Latest Stable Version](https://poser.pugx.org/phalapi/kernal/v/stable)](https://packagist.org/packages/phalapi/kernal)
[![Total Downloads](https://poser.pugx.org/phalapi/kernal/downloads)](https://packagist.org/packages/phalapi/kernal)
[![Latest Unstable Version](https://poser.pugx.org/phalapi/kernal/v/unstable)](https://packagist.org/packages/phalapi/kernal)
[![License](https://poser.pugx.org/phalapi/kernal/license)](https://packagist.org/packages/phalapi/kernal)
PhalApi 2.x 框架核心部分基于composer。

View File

@ -0,0 +1,35 @@
{
"name": "phalapi/kernal",
"description": "PhalApi 2.x 框架核心部分。",
"keywords": [
"api", "phalapi", "framework"
],
"license": "GPL-3.0+",
"homepage": "https://www.phalapi.net/",
"authors": [
{
"name": "Dogstar Huang",
"email": "chanzonghuang@gmail.com",
"homepage": "http://my.oschina.net/dogstar",
"role": "Developer"
},
{
"name": "kwan",
"email": "303198069@qq.com",
"role": "Developer"
}
],
"require": {
"php": ">=5.3.3",
"phalapi/notorm": "2.*.*"
},
"autoload": {
"files": [
"src/bootstrap.php",
"src/functions.php"
],
"psr-4": {
"PhalApi\\": "src"
}
}
}

View File

@ -0,0 +1,27 @@
<?php
return array(
/** ---------------------- framework translation - developer ---------------------- **/
'service ({service}) illegal' => 'service ({service}) illegal',
'no such service as {service}' => 'no such service as {service}',
'mcrypt_module_open with {cipher}' => 'mcrypt_module_open with {cipher}',
'No table map config for {tableName}' => 'No table map config for {tableName}',
'Call to undefined method PhalApi_DI::{name}() .' => 'Call to undefined method PhalApi_DI::{name}() .',
"miss {name}'s enum range" => "miss {name}'s enum range",
'{name} should be in {range}, but now {name} = {value}' => '{name} should be in {range}, but now {name} = {value}',
"min should <= max, but now {name} min = {min} and max = {max}" => 'min should <= max, but now {name} min = {min} and max = {max}',
'{name} should >= {min}, but now {name} = {value}' => '{name} should >= {min}, but now {name} = {value}',
'miss name for rule' => 'miss name for rule',
'{name} require, but miss' => '{name} require, but miss',
'PhalApi_Api::${name} undefined' => 'PhalApi_Api::${name} undefined',
'Bad Request: {message}' => 'Bad Request: {message}',
'Interal Server Error: {message}' => 'Interal Server Error: {message}',
"{name}'s enum range can not be empty" => "{name}'s enum range can not be empty",
'DI()->filter should be instanceof PhalApi_Filter' => 'DI()->filter should be instanceof PhalApi_Filter',
'wrong sign' => 'wrong sign',
'invalid type: {type} for rule: {name}' => 'invalid type: {type} for rule: {name}',
'invalid callback for rule: {name}' => 'invalid callback for rule: {name}',
'redis config key [socket] not found' => 'redis config key [socket] not found',
'{name} can not match {regex}' => '{name} can not match {regex}',
'missing {name} extension' => 'missing {name} extension',
);

View File

@ -0,0 +1,43 @@
<?php
/**
* 翻译说明:
* 1、带大括号的保留原来写法,如:{name},会被系统动态替换
* 2、没在以下出现的,可以自行追加
*/
return array(
/** ---------------------- 框架核心类库的翻译 - 开发维护 ---------------------- **/
'service ({service}) illegal' => '非法服务:{service}',
'no such service as {service}' => '接口服务{service}不存在',
'mcrypt_module_open with {cipher}' => 'mcrypt_module_open with {cipher}',
'No table map config for {tableName}' => '缺少表{tableName}的配置',
'Call to undefined method PhalApi_DI::{name}() .' => '调用了未定义的方法PhalApi_DI::{name}()',
"miss {name}'s enum range" => '{name}缺少枚举范围',
'{name} should be in {range}, but now {name} = {value}' => '参数{name}应该为:{range},但现在{name} = {value}',
"min should <= max, but now {name} min = {min} and max = {max}" => '最小值应该小于等于最大值,但现在{name}的最小值为:{min},最大值为:{max}',
'{name} should >= {min}, but now {name} = {value}' => '{name}应该大于或等于{min}, 但现在{name} = {value}',
'{name} should <= {max}, but now {name} = {value}' => '{name}应该小于等于{max}, 但现在{name} = {value}',
'miss name for rule' => '参数规则缺少name',
'{name} require, but miss' => '缺少必要参数{name}',
'PhalApi_Api::${name} undefined' => 'PhalApi_Api::${name} 未定义',
'Bad Request: {message}' => '非法请求:{message}',
'Interal Server Error: {message}' => '服务器运行错误: {message}',
'Redirect: {message}' => '重定向:{message}',
"{name}'s enum range can not be empty" => '{name}枚举规则中的range不能为空',
'no such db:{db} in servers' => '在servers中缺少{db}的配置',
'can not connect to database: {db}' => '数据库{db}连接失败',
'can not connect to database: {db}, code: {code}, cause: {msg}' => '数据库{db}连接失败,异常码:{code},错误原因:{msg}',
'miss upload file: {file}' => '缺少上传文件:{file}',
'fail to upload file with error = {error}' => '上传文件失败error = {error}',
'DI()->filter should be instanceof PhalApi_Filter' => 'DI()->filter未实现PhalApi_Filter接口',
'wrong sign' => '签名错误',
'invalid type: {type} for rule: {name}' => "{name}参数规则的类型({type})非法",
'invalid callback for rule: {name}' => '{name}参数规则的回调函数非法',
'Not the file type {ext}' => '上传失败不是文件类型 {ext}',
'{name} can not match {regex}' => '{name}无法匹配{regex}',
'redis config key [socket] not found' => 'redis配置键[socket]未设置',
'missing {name} extension' => '缺少{name}扩展',
'create file path Error: {filePath}' => '创建文件异常: {filePath}',
'unknow source: {source} in rule' => '参数规则中未知的数据源:{source}',
'{name} illegal json data' => '参数{name}的JSON数据格式错误',
);

View File

@ -0,0 +1,266 @@
<?php
namespace PhalApi;
use PhalApi\Exception\InternalServerErrorException;
/**
* Api 接口服务基类
*
* - 实现身份验证、按参数规则解析生成接口参数等操作
* - 提供给开发人员自宝义的接口服务具体类继承
*
* <br>通常地,可以这样继承:<br>
*
```
* class MyApi extends Api {
*
* public function getRules() {
* return array(
* // ...
* );
* }
*
* public function doSth() {
* $rs = array();
*
* // ...
*
* return $rs;
* }
* }
```
*
* @property mixed $whatever 接口参数
* @package PhalApi\Api
* @license http://www.phalapi.net/license GPL 协议 GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2014-10-02
*/
class Api {
/**
* @var boolean $__apiIsServiceWhitelist 是否为白名单服务
*/
private $__apiIsServiceWhitelist;
/**
* 设置规则解析后的接口参数
* @param string $name 接口参数名字
* @param mixed $value 接口参数解析后的值
*/
public function __set($name, $value) {
$this->$name = $value;
}
/**
* 获取规则解析后的接口参数
* @param string $name 接口参数名字
* @throws Exception_InternalServerError 获取未设置的接口参数时返回500
* @return mixed
*/
public function __get($name) {
if(!isset($this->$name) || empty($name)) {
throw new InternalServerErrorException(
T('Api::${name} undefined', array('name' => $name))
);
}
return $this->$name;
}
/**
* 初始化
*
* 主要完成的初始化工作有:
* - 1[必须]按参数规则解析生成接口参数
* - 2[可选]过滤器调用,如:签名验证
* - 3[可选]用户身份验证
*
* @uses Api::createMemberValue()
* @uses Api::filterCheck()
* @uses Api::userCheck()
* @return null
*/
public function init() {
$this->createMemberValue();
$this->filterCheck();
$this->userCheck();
}
/**
* 按参数规则解析生成接口参数
*
* 根据配置的参数规则,解析过滤,并将接口参数存放于类成员变量
*
* @uses Api::getApiRules()
*/
protected function createMemberValue() {
foreach ($this->getApiRules() as $key => $rule) {
$this->$key = DI()->request->getByRule($rule);
}
}
/**
* 取接口参数规则
*
* 主要包括有:
* - 1[固定]系统级的service参数
* - 2、应用级统一接口参数规则在app.apiCommonRules中配置
* - 3、接口级通常参数规则,在子类的*中配置
* - 4、接口级当前操作参数规则
*
* <b>当规则有冲突时,以后面为准。另外,被请求的函数名和配置的下标都转成小写再进行匹配。</b>
*
* @uses Api::getRules()
* @return array
*/
public function getApiRules() {
$rules = array();
$allRules = $this->getRules();
if (!is_array($allRules)) {
$allRules = array();
}
$allRules = array_change_key_case($allRules, CASE_LOWER);
$action = strtolower(DI()->request->getServiceAction());
if (isset($allRules[$action]) && is_array($allRules[$action])) {
$rules = $allRules[$action];
}
if (isset($allRules['*'])) {
$rules = array_merge($allRules['*'], $rules);
}
$apiCommonRules = DI()->config->get('app.apiCommonRules', array());
if (!empty($apiCommonRules) && is_array($apiCommonRules)) {
// fixed issue #22
if ($this->isServiceWhitelist()) {
foreach ($apiCommonRules as &$ruleRef) {
$ruleRef['require'] = false;
}
}
$rules = array_merge($apiCommonRules, $rules);
}
return $rules;
}
/**
* 获取参数设置的规则
*
* 可由开发人员根据需要重载
*
* @return array
*/
public function getRules() {
return array();
}
/**
* 过滤器调用
*
* 可由开发人员根据需要重载,以实现项目拦截处理,需要:
* - 1、实现Filter::check()接口
* - 2、注册的过滤器到DI()->filter
*
* <br>以下是一个简单的示例:<br>
```
* class MyFilter implements Filter {
*
* public function check() {
* //TODO
* }
* }
*
*
* //在初始化文件 init.php 中注册过滤器
* DI()->filter = 'MyFilter';
```
*
* @see Filter::check()
* @throws Exception_BadRequest 当验证失败时请抛出此异常以返回400
*/
protected function filterCheck() {
// 过滤服务白名单
if ($this->isServiceWhitelist()) {
return;
}
$filter = DI()->get('filter', '\\PhalApi\\Filter\\NoneFilter');
if (isset($filter)) {
if (!($filter instanceof Filter)) {
throw new InternalServerErrorException(
T('DI()->filter should be instanceof \PhalApi\Filter'));
}
$filter->check();
}
}
/**
* 用户身份验证
*
* 可由开发人员根据需要重载,此通用操作一般可以使用委托或者放置在应用接口基类
*
* @throws Exception_BadRequest 当验证失败时请抛出此异常以返回400
*/
protected function userCheck() {
}
/**
* 是否为白名单的服务
*
* @return boolean
*/
protected function isServiceWhitelist() {
// 缓存返回,避免重复计算
if ($this->__apiIsServiceWhitelist !== NULL) {
return $this->__apiIsServiceWhitelist;
}
$this->__apiIsServiceWhitelist = FALSE;
$di = DI();
$api = $di->request->getServiceApi();
$action = $di->request->getServiceAction();
$namespace = $di->request->getNamespace();
// 优先命名空间的单独白名单配置,再到公共白名单配置
$serviceWhitelist = $di->config->get('app.service_whitelist.' . $namespace);
$serviceWhitelist = $serviceWhitelist !== NULL
? $serviceWhitelist : $di->config->get('app.service_whitelist', array());
foreach ($serviceWhitelist as $item) {
$cfgArr = is_string($item) ? explode('.', $item) : array();
if (count($cfgArr) < 2) {
continue;
}
// 短路返回
if ($this->equalOrIngore($api, $cfgArr[0]) && $this->equalOrIngore($action, $cfgArr[1])) {
$this->__apiIsServiceWhitelist = TRUE;
break;
}
}
return $this->__apiIsServiceWhitelist;
}
/**
* 相等或忽略
*
* @param string $str 等判断的字符串
* @param string $cfg 规则配置,*号表示通配
* @return boolean
*/
private function equalOrIngore($str, $cfg) {
return strcasecmp($str, $cfg) == 0 || $cfg == '*';
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace PhalApi;
use PhalApi\Exception\BadRequestException;
use PhalApi\Exception\InternalServerErrorException;
/**
* ApiFactory 创建控制器类 工厂方法
*
* 将创建与使用分离,简化客户调用,负责控制器复杂的创建过程
*
```
* //根据请求(?service=XXX.XXX)生成对应的接口服务,并进行初始化
* $api = ApiFactory::generateService();
```
* @package PhalApi\Api
* @license http://www.phalapi.net/license GPL 协议 GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2014-10-02
*/
class ApiFactory {
/**
* 创建服务器
* 根据客户端提供的接口服务名称和需要调用的方法进行创建工作,如果创建失败,则抛出相应的自定义异常
*
* 创建过程主要如下:
* - 1 是否缺少控制器名称和需要调用的方法
* - 2 控制器文件是否存在,并且控制器是否存在
* - 3 方法是否可调用
* - 4 控制器是否初始化成功
*
* @param boolen $isInitialize 是否在创建后进行初始化
* @param string $_REQUEST['service'] 接口服务名称格式XXX.XXX
* @return \PhalApi\Api 自定义的控制器
*
* @uses \PhalApi\Api::init()
* @throws BadRequestException 非法请求下返回400
*/
static function generateService($isInitialize = TRUE) {
$di = DI();
$service = $di->request->getService();
$namespace = $di->request->getNamespace();
$api = $di->request->getServiceApi();
$action = $di->request->getServiceAction();
if (empty($api) || empty($action)) {
throw new BadRequestException(
T('service ({service}) illegal', array('service' => $service))
);
}
$apiClass = '\\' . str_replace('_', '\\', $namespace)
. '\\Api\\' . str_replace('_', '\\', ucfirst($api));
if (!class_exists($apiClass)) {
throw new BadRequestException(
T('no such service as {service}', array('service' => $service)), 4
);
}
$api = new $apiClass();
if (!is_subclass_of($api, '\\PhalApi\\Api')) {
throw new InternalServerErrorException(
T('{class} should be subclass of \\PhalApi\\Api', array('class' => $apiClass))
);
}
if (!method_exists($api, $action) || !is_callable(array($api, $action))) {
throw new BadRequestException(
T('no such service as {service}', array('service' => $service)), 4
);
}
if ($isInitialize) {
$api->init();
}
return $api;
}
}

View File

@ -0,0 +1,225 @@
<?php
namespace PhalApi;
use PhalApi\Exception\InternalServerErrorException;
/**
* CUrl CURL请求类
*
* 通过curl实现的快捷方便的接口请求类
*
* <br>示例:<br>
*
```
* // 失败时再重试2次
* $curl = new CUrl(2);
*
* // GET
* $rs = $curl->get('http://phalapi.oschina.mopaas.com/Public/demo/?service=Default.Index');
*
* // POST
* $data = array('username' => 'dogstar');
* $rs = $curl->post('http://phalapi.oschina.mopaas.com/Public/demo/?service=Default.Index', $data);
```
*
* @package PhalApi\CUrl
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2015-01-02
*/
class CUrl {
/**
* 最大重试次数
*/
const MAX_RETRY_TIMES = 10;
/**
* @var int $retryTimes 超时重试次数;注意,此为失败重试的次数,即:总次数 = 1 + 重试次数
*/
protected $retryTimes;
protected $header = array();
protected $option = array();
protected $hascookie = FALSE;
protected $cookie = array();
/**
* @param int $retryTimes 超时重试次数默认为1
*/
public function __construct($retryTimes = 1) {
$this->retryTimes = $retryTimes < static::MAX_RETRY_TIMES
? $retryTimes : static::MAX_RETRY_TIMES;
}
/** ------------------ 核心使用方法 ------------------ **/
/**
* GET方式的请求
* @param string $url 请求的链接
* @param int $timeoutMs 超时设置,单位:毫秒
* @return string 接口返回的内容超时返回false
*/
public function get($url, $timeoutMs = 3000) {
return $this->request($url, array(), $timeoutMs);
}
/**
* POST方式的请求
* @param string $url 请求的链接
* @param array $data POST的数据
* @param int $timeoutMs 超时设置,单位:毫秒
* @return string 接口返回的内容超时返回false
*/
public function post($url, $data, $timeoutMs = 3000) {
return $this->request($url, $data, $timeoutMs);
}
/** ------------------ 前置方法 ------------------ **/
/**
* 设置请求头,后设置的会覆盖之前的设置
*
* @param array $header 传入键值对如:
```
* array(
* 'Accept' => 'text/html',
* 'Connection' => 'keep-alive',
* )
```
*
* @return $this
*/
public function setHeader($header) {
$this->header = array_merge($this->header, $header);
return $this;
}
/**
* 设置curl配置项
*
* - 1、后设置的会覆盖之前的设置
* - 2、开发者设置的会覆盖框架的设置
*
* @param array $option 格式同上
*
* @return $this
*/
public function setOption($option) {
$this->option = $option + $this->option;
return $this;
}
/**
* @param array $cookie
*/
public function setCookie($cookie) {
$this->cookie = $cookie;
return $this;
}
/**
* @return array
*/
public function getCookie() {
return $this->cookie;
}
public function withCookies() {
$this->hascookie = TRUE;
if (!empty($this->cookie)) {
$this->setHeader(array('Cookie' => $this->getCookieString()));
}
$this->setOption(array(CURLOPT_COOKIEFILE => ''));
return $this;
}
/** ------------------ 辅助方法 ------------------ **/
/**
* 统一接口请求
* @param string $url 请求的链接
* @param array $data POST的数据
* @param int $timeoutMs 超时设置,单位:毫秒
* @return string 接口返回的内容超时返回false
* @throws Exception
*/
protected function request($url, $data, $timeoutMs = 3000) {
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => 0,
CURLOPT_CONNECTTIMEOUT_MS => $timeoutMs,
CURLOPT_HTTPHEADER => $this->getHeaders(),
);
if (!empty($data)) {
$options[CURLOPT_POST] = 1;
$options[CURLOPT_POSTFIELDS] = $data;
}
$options = $this->option + $options; //$this->>option优先
$ch = curl_init();
curl_setopt_array($ch, $options);
$curRetryTimes = $this->retryTimes;
do {
$rs = curl_exec($ch);
$curRetryTimes--;
} while ($rs === FALSE && $curRetryTimes >= 0);
$errno = curl_errno($ch);
if ($errno) {
throw new InternalServerErrorException(sprintf("%s::%s(%d)\n", $url, curl_error($ch), $errno));
}
//update cookie
if ($this->hascookie) {
$cookie = $this->getRetCookie(curl_getinfo($ch, CURLINFO_COOKIELIST));
!empty($cookie) && $this->cookie = $cookie + $this->cookie;
$this->hascookie = FALSE;
unset($this->header['Cookie']);
unset($this->option[CURLOPT_COOKIEFILE]);
}
curl_close($ch);
return $rs;
}
/**
*
* @return array
*/
protected function getHeaders() {
$arrHeaders = array();
foreach ($this->header as $key => $val) {
$arrHeaders[] = $key . ': ' . $val;
}
return $arrHeaders;
}
protected function getRetCookie(array $cookies) {
$ret = array();
foreach ($cookies as $cookie) {
$arr = explode("\t", $cookie);
if (!isset($arr[6])) {
continue;
}
$ret[$arr[5]] = $arr[6];
}
return $ret;
}
protected function getCookieString() {
$ret = '';
foreach ($this->getCookie() as $key => $val) {
$ret .= $key . '=' . $val . ';';
}
return trim($ret, ';');
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace PhalApi;
/**
* PhalApi\Cache 缓存接口
*
* @package PhalApi\Cache
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2015-02-04
*/
interface Cache {
/**
* 设置缓存
*
* @param string $key 缓存key
* @param mixed $value 缓存的内容
* @param int $expire 缓存有效时间,单位秒,非时间戳
*/
public function set($key, $value, $expire = 600);
/**
* 读取缓存
*
* @param string $key 缓存key
* @return mixed 失败情况下返回NULL
*/
public function get($key);
/**
* 删除缓存
*
* @param string $key
*/
public function delete($key);
}

View File

@ -0,0 +1,38 @@
<?php
namespace PhalApi\Cache;
use PhalApi\Cache;
use PhalApi\Exception\InternalServerErrorException;
/**
* APCUCache APC User Cache
*
* @package PhalApi\Cache
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2017-04-14
*/
class APCUCache {
public function __construct() {
if (!extension_loaded('apcu')) {
throw new InternalServerErrorException(
\PhalApi\T('missing {name} extension', array('name' => 'apcu'))
);
}
}
public function set($key, $value, $expire = 600) {
return apcu_store($key, $value, $expire);
}
public function get($key) {
$value = apcu_fetch($key);
return $value !== FALSE ? $value : NULL;
}
public function delete($key) {
return apcu_delete($key);
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace PhalApi\Cache;
use PhalApi\Cache;
use PhalApi\Exception\InternalServerErrorException;
/**
* FileCache 文件缓存
*
* @package PhalApi\Cache
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2015-02-26
*/
class FileCache implements Cache {
/**
* @var string $folder 文件缓存保存的目录
*/
protected $folder;
/**
* @var string $prefix 文件缓存的key前缀
*/
protected $prefix;
/**
* @var boolean $enableFileNameFormat 是否格式化文件名
*/
protected $enableFileNameFormat = TRUE;
public function __construct($config) {
$this->folder = rtrim($config['path'], '/');
$cacheFolder = $this->createCacheFileFolder();
if (!is_dir($cacheFolder)) {
mkdir($cacheFolder, 0777, TRUE);
}
$this->prefix = isset($config['prefix']) ? $config['prefix'] : 'phapapi';
$this->enableFileNameFormat = isset($config['enable_file_name_format']) ? (boolean)$config['enable_file_name_format'] : $this->enableFileNameFormat;
}
public function set($key, $value, $expire = 600) {
if ($key === NULL || $key === '') {
return;
}
$filePath = $this->createCacheFilePath($key);
$expireStr = sprintf('%010d', $expire + time());
if (strlen($expireStr) > 10) {
throw new InternalServerErrorException(
\PhalApi\T('file expire is too large')
);
}
if (!file_exists($filePath)) {
touch($filePath);
chmod($filePath, 0777);
}
file_put_contents($filePath, $expireStr . serialize($value));
}
public function get($key) {
$filePath = $this->createCacheFilePath($key);
if (file_exists($filePath)) {
$expireTime = file_get_contents($filePath, FALSE, NULL, 0, 10);
if ($expireTime > time()) {
return @unserialize(file_get_contents($filePath, FALSE, NULL, 10));
}
}
return NULL;
}
public function delete($key) {
if ($key === NULL || $key === '') {
return;
}
$filePath = $this->createCacheFilePath($key);
@unlink($filePath);
}
/**
* 考虑到Linux同一目录下的文件个数限制这里拆分成1000个文件缓存目录
*/
protected function createCacheFilePath($key) {
$folderSufix = sprintf('%03d', hexdec(substr(sha1($key), -5)) % 1000);
$cacheFolder = $this->createCacheFileFolder() . DIRECTORY_SEPARATOR . $folderSufix;
if (!is_dir($cacheFolder)) {
mkdir($cacheFolder, 0777, TRUE);
}
// 避免撞key增强唯一性
$filename = $this->enableFileNameFormat ?
sprintf('%s_%s_%s_%s.dat', md5($this->prefix), strlen($this->prefix), md5($key), strlen($key))
: $this->prefix . $key;
return $cacheFolder . DIRECTORY_SEPARATOR . $filename;
}
protected function createCacheFileFolder() {
return $this->folder . DIRECTORY_SEPARATOR . 'cache';
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace PhalApi\Cache;
use PhalApi\Cache;
/**
* MemcacheCache MC缓存
*
* - 使用序列化对需要存储的值进行转换,以提高速度
* - 默认不使用zlib对值压缩
* - 请尽量使用Memcached扩展
*
* @package PhalApi\Cache
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author PhpStorm George <plzhuangyuan@163.com> 15/5/6 下午8:53
*/
class MemcacheCache implements Cache {
protected $memcache = null;
protected $prefix;
/**
* @param string $config['host'] Memcache域名多个用英文逗号分割
* @param int/string $config['port'] Memcache端口多个用英文逗号分割
* @param int/string $config['weight'] Memcache权重多个用英文逗号分割
* @param string $config['prefix'] Memcache key prefix
*/
public function __construct($config) {
$this->memcache = $this->createMemcache();
$hostArr = explode(',', $config['host']);
$portArr = explode(',', $config['port']);
$weightArr = isset($config['weight']) ? explode(',', $config['weight']) : array();
foreach ($hostArr as $idx => $host) {
$this->memcache->addServer(
trim($host),
isset($portArr[$idx]) ? intval($portArr[$idx]) : 11211,
isset($weightArr[$idx]) ? intval($weightArr[$idx]) : 0
);
}
$this->prefix = isset($config['prefix']) ? $config['prefix'] : 'phalapi_';
}
public function set($key, $value, $expire = 600) {
$this->memcache->set($this->formatKey($key), @serialize($value), 0, $expire);
}
public function get($key) {
$value = $this->memcache->get($this->formatKey($key));
return $value !== FALSE ? @unserialize($value) : NULL;
}
public function delete($key) {
return $this->memcache->delete($this->formatKey($key));
}
/**
* 获取MC实例以便提供桩入口
* @return Memcache
*/
protected function createMemcache() {
return new \Memcache();
}
protected function formatKey($key) {
return $this->prefix . $key;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace PhalApi\Cache;
use PhalApi\Cache\MemcacheCache;
/**
* MemcachedCache MC缓存
*
* - 使用序列化对需要存储的值进行转换,以提高速度
*
* @package PhalApi\Cache
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2014-11-14
*/
class MemcachedCache extends MemcacheCache {
/**
* 注意参数的微妙区别
*/
public function set($key, $value, $expire = 600) {
$this->memcache->set($this->formatKey($key), @serialize($value), $expire);
}
/**
* 返回更高版本的MC实例
* @return Memcached
*/
protected function createMemcache() {
return new \Memcached();
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace PhalApi\Cache;
use PhalApi\Cache;
/**
* MultiCache 组合模式下的多级缓存
*
* - 可以自定义添加多重缓存,注意优先添加高效缓存
* - 最终将委托给各级缓存进行数据的读写,其中读取为短路读取
*
* @package PhalApi\Cache
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2015-02-22
*/
class MultiCache implements Cache {
protected $caches = array();
public function addCache(Cache $cache) {
$this->caches[] = $cache;
}
public function set($key, $value, $expire = 600) {
foreach ($this->caches as $cache) {
$cache->set($key, $value, $expire);
}
}
public function get($key) {
foreach ($this->caches as $cache) {
$value = $cache->get($key);
if ($value !== NULL) {
return $value;
}
}
return NULL;
}
public function delete($key) {
foreach ($this->caches as $cache) {
$cache->delete($key);
}
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhalApi\Cache;
use PhalApi\Cache;
/**
* NoneCache 空缓存 - NULL-Object空对象模式
*
* @package PhalApi\Cache
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2015-02-04
*/
class NoneCache implements Cache {
public function set($key, $value, $expire = 600) {
}
public function get($key) {
return NULL;
}
public function delete($key) {
}
}

View File

@ -0,0 +1,118 @@
<?php
namespace PhalApi\Cache;
use PhalApi\Cache;
use PhalApi\Exception\InternalServerErrorException;
/**
* RedisCache Redis缓存
*
* - 使用序列化对需要存储的值进行转换,以提高速度
* - 提供更多redis的操作以供扩展类库使用
*
* @package PhalApi\Cache
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author zzguo 2015-5-11
* @modify dogstar <chanzonghuang@gmail.com> 20150516
*/
class RedisCache implements Cache {
protected $redis;
protected $auth;
protected $prefix;
/**
* @param string $config['type'] Redis连接方式 unix,http
* @param string $config['socket'] unix方式连接时需要配置
* @param string $config['host'] Redis域名
* @param int $config['port'] Redis端口,默认为6379
* @param string $config['prefix'] Redis key prefix
* @param string $config['auth'] Redis 身份验证
* @param int $config['db'] Redis库,默认0
* @param int $config['timeout'] 连接超时时间,单位秒,默认300
*/
public function __construct($config) {
$this->redis = new \Redis();
// 连接
if (isset($config['type']) && $config['type'] == 'unix') {
if (!isset($config['socket'])) {
throw new InternalServerErrorException(\PhalApi\T('redis config key [socket] not found'));
}
$this->redis->connect($config['socket']);
} else {
$port = isset($config['port']) ? intval($config['port']) : 6379;
$timeout = isset($config['timeout']) ? intval($config['timeout']) : 300;
$this->redis->connect($config['host'], $port, $timeout);
}
// 验证
$this->auth = isset($config['auth']) ? $config['auth'] : '';
if ($this->auth != '') {
$this->redis->auth($this->auth);
}
// 选择
$dbIndex = isset($config['db']) ? intval($config['db']) : 0;
$this->redis->select($dbIndex);
$this->prefix = isset($config['prefix']) ? $config['prefix'] : 'phalapi:';
}
/**
* 将value 的值赋值给key,生存时间为expire秒
*/
public function set($key, $value, $expire = 600) {
$this->redis->setex($this->formatKey($key), $expire, $this->formatValue($value));
}
public function get($key) {
$value = $this->redis->get($this->formatKey($key));
return $value !== FALSE ? $this->unformatValue($value) : NULL;
}
public function delete($key) {
return $this->redis->delete($this->formatKey($key));
}
/**
* 检测是否存在key,若不存在则赋值value
*/
public function setnx($key, $value) {
return $this->redis->setnx($this->formatKey($key), $this->formatValue($value));
}
public function lPush($key, $value) {
return $this->redis->lPush($this->formatKey($key), $this->formatValue($value));
}
public function rPush($key, $value) {
return $this->redis->rPush($this->formatKey($key), $this->formatValue($value));
}
public function lPop($key) {
$value = $this->redis->lPop($this->formatKey($key));
return $value !== FALSE ? $this->unformatValue($value) : NULL;
}
public function rPop($key) {
$value = $this->redis->rPop($this->formatKey($key));
return $value !== FALSE ? $this->unformatValue($value) : NULL;
}
protected function formatKey($key) {
return $this->prefix . $key;
}
protected function formatValue($value) {
return @serialize($value);
}
protected function unformatValue($value) {
return @unserialize($value);
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace PhalApi;
/**
* Config 配置接口
*
* 获取系统所需要的参数配置
*
* <br>使用示例:<br>
```
* //假设有这样的app.php配置
* return array(
* 'version' => '1.1.1',
*
* 'email' => array(
* 'address' => 'chanzonghuang@gmail.com',
* );
* );
*
* //我们就可以分别这样根据需要获取配置:
* //app.php里面的全部配置
* DI()->config->get('app');
*
* //app.php里面的单个配置
* DI()->config->get('app.version'); //返回1.1.1
*
* //app.php里面的多级配置
* DI()->config->get('app.version.address'); //返回chanzonghuang@gmail.com
```
*
* @package PhalApi\Config
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2014-10-02
*/
interface Config {
/**
* 获取配置
*
* @param $key string 配置键值
* @param mixed $default 缺省值
* @return mixed 需要获取的配置值,不存在时统一返回$default
*/
public function get($key, $default = NULL);
}

View File

@ -0,0 +1,82 @@
<?php
namespace PhalApi\Config;
use PhalApi\Config;
/**
* FileConfig 文件配置类
*
* <li>从配置文件获取参数配置</li>
*
* 使用示例:
* <br>
* <code>
* $config = new FileConfig('./Config');
* $config->get('sys.db.user');
* </code>
*
* @package PhalApi\Config
* @see \PhalApi\Config::get()
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2014-10-02
*/
class FileConfig implements Config {
/**
* @var string $path 配置文件的目录位置
*/
private $path = '';
/**
* @var array $map 配置文件的映射表,避免重复加载
*/
private $map = array();
public function __construct($configPath) {
$this->path = $configPath;
}
/**
* 获取配置
* 首次获取时会进行初始化
*
* @param $key string 配置键值
* @return mixed 需要获取的配置值
*/
public function get($key, $default = NULL) {
$keyArr = explode('.', $key);
$fileName = $keyArr[0];
if (!isset($this->map[$fileName])) {
$this->loadConfig($fileName);
}
$rs = NULL;
$preRs = $this->map;
foreach ($keyArr as $subKey) {
if (!isset($preRs[$subKey])) {
$rs = NULL;
break;
}
$rs = $preRs[$subKey];
$preRs = $rs;
}
return $rs !== NULL ? $rs : $default;
}
/**
* 加载配置文件
* 加载保存配置信息数组的config.php文件若文件不存在则将$map置为空数组
*
* @param string $fileName 配置文件路径
* @return array 配置文件对应的内容
*/
private function loadConfig($fileName) {
$config = include($this->path . DIRECTORY_SEPARATOR . $fileName . '.php');
$this->map[$fileName] = $config;
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace PhalApi\Config;
use PhalApi\Config;
/**
* YaconfConfig Yaconf扩展配置类
*
* - 通过Yaconf扩展快速获取配置
*
* 使用示例:
```
* <code>
* $config = new YaconfConfig();
*
* var_dump($config->get('foo')); //相当于var_dump(Yaconf::get("foo"));
*
* var_dump($config->has('foo')); //相当于var_dump(Yaconf::has("foo"));
* </code>
```
*
* @package PhalApi\Config
* @see \PhalApi\Config::get()
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @link https://github.com/laruence/yaconf
* @author dogstar <chanzonghuang@gmail.com> 2014-10-02
*/
class YaconfConfig implements Config {
public function get($key, $default = NULL) {
return \Yaconf::get($key, $default);
}
public function has($key) {
return \Yaconf::has($key);
}
}

View File

@ -0,0 +1,107 @@
<?php
namespace PhalApi;
/**
* Cookie COOKIE操作
*
* - 原生态COOKIE操作的简单封装
* - 注意设置的COOKIE需要在下一次才能生效
*
* <br>使用示例:<br>
```
* //COOKIE
* DI()->cookie = 'Cookie';
*
* //设置COOKIE服务
* DI()->cookie->set('name', 'phalapi', $_SERVER['REQUEST_TIME'] + 600);
*
* //获取
* echo DI()->cookie->get('name'); //输出 phalapi
*
* //删除
* DI()->cookie->delete('name');
*
```
* @package PhalApi\Cookie
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2015-04-11
*/
class Cookie {
/**
* COOKIE配置
*/
protected $config = array();
/**
* @param string $config['path'] 路径
* @param string $config['domain'] 域名
* @param boolean $config['secure'] 是否加密
* @param boolean $config['httponly'] 是否只HTTP协议
* @link http://php.net/manual/zh/function.setcookie.php
*/
public function __construct($config = array()) {
$this->config['path'] = isset($config['path']) ? $config['path'] : NULL;
$this->config['domain'] = isset($config['domain']) ? $config['domain'] : NULL;
$this->config['secure'] = isset($config['secure']) ? $config['secure'] : FALSE;
$this->config['httponly'] = isset($config['httponly']) ? $config['httponly'] : FALSE;
}
/**
* 获取COOKIE
*
* @param string $name 待获取的COOKIE名字
* @return string/NULL/array $name为NULL时返回整个$_COOKIE存在时返回COOKIE否则返回NULL
*/
public function get($name = NULL) {
if ($name === NULL) {
return $_COOKIE;
}
return isset($_COOKIE[$name]) ? $_COOKIE[$name] : NULL;
}
/**
* 设置COOKIE
*
* @param string $name 待设置的COOKIE名字
* @param string/int $value 建议COOKIE值为一些简单的字符串或数字不推荐存放敏感数据
* @param int $expire 有效期的timestamp为NULL时默认存放一个月
* @param boolean
*/
public function set($name, $value, $expire = NULL) {
if ($expire === NULL) {
$expire = $_SERVER['REQUEST_TIME'] + 2592000; //a month
}
return setcookie(
$name,
$value,
$expire,
$this->config['path'],
$this->config['domain'],
$this->config['secure'],
$this->config['httponly']
);
}
/**
* 删除COOKIE
*
* @param strint $name 待删除的COOKIE名字
* @param boolean
* @see Cookie::set()
*/
public function delete($name) {
return $this->set($name, '', 0);
}
/**
* 获取COOKIE的配置
*/
public function getConfig() {
return $this->config;
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace PhalApi\Cookie;
use PhalApi\Cookie;
use PhalApi\Crypt;
/**
* MultiCookie 多级COOKIE
*
* - 使用crypt进行加解密
* - 带记忆功能,即设置后此时能获取
*
* @package PhalApi\Cookie
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2015-04-11
*/
class MultiCookie extends Cookie {
/**
* @param $config['crypt'] 加密的服务如果未设置默认取DI()->crypt须实现PhalApi_Crypt接口
* @param $config['key'] $config['crypt']用的密钥未设置时有一个md5串
*/
public function __construct($config = array()) {
parent::__construct($config);
$this->config['crypt'] = isset($config['crypt']) ? $config['crypt'] : \PhalAPi\DI()->crypt;
if (isset($config['crypt']) && $config['crypt'] instanceof Crypt) {
$this->config['key'] = isset($config['key'])
? $config['key'] : 'debcf37743b7c835ba367548f07aadc3';
} else {
$this->config['crypt'] = NULL;
}
}
/**
* 解密获取COOKIE
* @see PhalApi_Cookie::get()
*/
public function get($name = NULL) {
$rs = parent::get($name);
if (!isset($this->config['crypt'])) {
return $rs;
}
if (is_array($rs)) {
foreach ($rs as &$valueRef) {
$this->config['crypt']->decrypt($valueRef, $this->config['key']);
}
} else if ($rs !== NULL) {
$rs = $this->config['crypt']->decrypt($rs, $this->config['key']);
}
return $rs;
}
/**
* 加密设置COOKIE&记忆功能
* @see PhalApi_Cookie::set()
*/
public function set($name, $value, $expire = NULL) {
if (isset($this->config['crypt'])) {
$value = $this->config['crypt']->encrypt($value, $this->config['key']);
}
$_COOKIE[$name] = $value;
if ($expire < $_SERVER['REQUEST_TIME']) {
unset($_COOKIE[$name]);
}
return parent::set($name, $value, $expire);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace PhalApi;
/**
* Crypt对称加密接口
*
* @package PhalApi\Crypt
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2014-12-10
*/
interface Crypt {
/**
* 对称加密
*
* @param mixed $data 等加密的数据
* @param string $key 加密的key
* @return mixed 加密后的数据
*/
public function encrypt($data, $key);
/**
* 对称解密
*
* @see Crypt::encrypt()
* @param mixed $data 对称加密后的内容
* @param string $key 加密的key
* @return mixed 解密后的数据
*/
public function decrypt($data, $key);
}

View File

@ -0,0 +1,141 @@
<?php
namespace PhalApi\Crypt;
use PhalApi\Crypt;
use PhalApi\Exception\InternalServerErrorException;
/**
* McryptCrypt 原始mcrypt加密
*
* 使用mcrypt扩展进加解密
*
* <br>使用示例:<br>
```
* $mcrypt = new McryptCrypt('12345678');
*
* $data = 'dogstar love php';
* $key = 'secrect';
*
* // 加密
* $encryptData = $mcrypt->encrypt($data, $key);
*
* // 解密
* $decryptData = $mcrypt->decrypt($encryptData, $key);
```
*
* @package PhalApi\Crypt
* @link http://php.net/manual/zh/function.mcrypt-generic.php
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2014-12-10
*/
class McryptCrypt implements Crypt {
/**
* @var string $iv 加密向量, 最大长度不得超过McryptCrypt::MAX_IV_SIZE
*/
protected $iv;
/**
* @var int 最大加密向量长度
*/
const MAX_IV_SIZE = 8;
/**
* @var int 最大加密key的长度
*/
const MAX_KEY_LENGTH = 56;
/**
* @param string $iv 加密的向量 最大长度不得超过 MAX_IV_SIZE
*/
public function __construct($iv = '********') {
$this->iv = str_pad($iv, static::MAX_IV_SIZE, '*');
if (strlen($this->iv) > static::MAX_IV_SIZE) {
$this->iv = substr($this->iv, 0, static::MAX_IV_SIZE);
}
}
/**
* 对称加密
*
* @param string $data 待加密的数据
* @param string key 私钥
* @return string 加密后的数据
*/
public function encrypt($data, $key) {
if ($data === '') {
return $data;
}
$cipher = $this->createCipher($key);
$encrypted = mcrypt_generic($cipher, $data);
$this->clearCipher($cipher);
return $encrypted;
}
/**
* 对称解密
*
* @see McryptCrypt::encrypt()
*
* @param string $data 待解密的数据
* @param string key 私钥
* @return string 解密后的数据
*/
public function decrypt($data, $key) {
if ($data === '') {
return $data;
}
$cipher = $this->createCipher($key);
$decrypted = mdecrypt_generic($cipher, $data);
$this->clearCipher($cipher);
return rtrim($decrypted, "\0");
}
/**
* 创建cipher
* @param string $key 私钥
* @return resource
* @throws PhalApi\Exception\InternalServerErrorException
*/
protected function createCipher($key) {
$cipher = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');
if ($cipher === FALSE || $cipher < 0) {
throw new InternalServerErrorException(
\PhalApi\T('mcrypt_module_open with {cipher}', array('cipher' => $cipher))
);
}
mcrypt_generic_init($cipher, $this->formatKey($key), $this->iv);
return $cipher;
}
/**
* 格式化私钥
* @param string $key 私钥
*/
protected function formatKey($key) {
return strlen($key) > static::MAX_KEY_LENGTH ? substr($key, 0, static::MAX_KEY_LENGTH) : $key;
}
/**
* 释放cipher
* @param resource $cipher
*/
protected function clearCipher($cipher) {
mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);
}
}

View File

@ -0,0 +1,64 @@
<?php
namespace PhalApi\Crypt;
use PhalApi\Crypt;
use PhalApi\Crypt\McryptCrypt;
/**
* MultiMcryptCrypt 多级mcrypt加密
* 对底层的mcrypt进行简单的再封装以便存储和保留类型
*
* - 依赖PhalApi_Crypt_Mcrypt进行加解密操作
* - 支持任何数据类型的加解密
* - 返回便于存储的字符串
*
* @package PhalApi\Crypt
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar <chanzonghuang@gmail.com> 2014-12-11
*/
class MultiMcryptCrypt implements Crypt {
/**
* @var PhalApi_Crypt_Mcrypt $mcrypt
*/
protected $mcrypt = NULL;
public function __construct($iv) {
$this->mcrypt = new McryptCrypt($iv);
}
/**
* @param mixed $data 待加密的数据
*/
public function encrypt($data, $key) {
$encryptData = serialize($data);
$encryptData = $this->mcrypt->encrypt($encryptData, $key);
$encryptData = base64_encode($encryptData);
return $encryptData;
}
/**
* 忽略不能正常反序列化的操作,并且在不能预期解密的情况下返回原文
*/
public function decrypt($data, $key) {
$decryptData = base64_decode($data);
if ($decryptData === FALSE || $decryptData === '') {
return FALSE;
}
$decryptData = $this->mcrypt->decrypt($decryptData, $key);
$decryptData = @unserialize($decryptData);
if ($decryptData === FALSE) {
return FALSE;
}
return $decryptData;
}
}

Some files were not shown because too many files have changed in this diff Show More