Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
goods
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
bp
goods
Commits
7b4d4a9f
Commit
7b4d4a9f
authored
Jun 15, 2021
by
luhongguang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add:test
parent
067601ba
Changes
48
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
3164 additions
and
0 deletions
+3164
-0
GoodsException.php
application/exception/custom/GoodsException.php
+29
-0
EditSetmealValidate.php
application/library/Validate/EditSetmealValidate.php
+25
-0
EditStoresValidate.php
application/library/Validate/EditStoresValidate.php
+31
-0
GoodsAuditValidate.php
application/library/Validate/GoodsAuditValidate.php
+27
-0
SetmealListValidate.php
application/library/Validate/SetmealListValidate.php
+21
-0
StoresListValidate.php
application/library/Validate/StoresListValidate.php
+21
-0
Category.php
application/models/goods/mysql/Category.php
+27
-0
GoodsOperationRecord.php
application/models/goods/mysql/GoodsOperationRecord.php
+36
-0
GoodsSku.php
application/models/goods/mysql/GoodsSku.php
+52
-0
GoodsSkuStores.php
application/models/goods/mysql/GoodsSkuStores.php
+45
-0
GoodsSnapshot.php
application/models/goods/mysql/GoodsSnapshot.php
+37
-0
GoodsSpu.php
application/models/goods/mysql/GoodsSpu.php
+55
-0
InventoryOperationRecord.php
application/models/goods/mysql/InventoryOperationRecord.php
+37
-0
Setmeal.php
application/models/goods/mysql/Setmeal.php
+50
-0
Shop.php
application/models/goods/mysql/Shop.php
+48
-0
Stores.php
application/models/goods/mysql/Stores.php
+50
-0
Goods.php
application/modules/Goods/controllers/Goods.php
+172
-0
CategoryService.php
application/services/goods/CategoryService.php
+32
-0
GoodsService.php
application/services/goods/GoodsService.php
+240
-0
SetmealService.php
application/services/goods/SetmealService.php
+99
-0
StoresService.php
application/services/goods/StoresService.php
+53
-0
XhMongo.php
vendor/api/php_services/src/XhProfiler/XhMongo.php
+31
-0
XhProfilerService.php
vendor/api/php_services/src/XhProfiler/XhProfilerService.php
+62
-0
Ks3Util.php
vendor/api/php_utils/src/Ksy/Ks3Util.php
+139
-0
AUTHORS
vendor/perftools/php-profiler/AUTHORS
+2
-0
LICENSE
vendor/perftools/php-profiler/LICENSE
+22
-0
README.md
vendor/perftools/php-profiler/README.md
+417
-0
autoload.php
vendor/perftools/php-profiler/autoload.php
+26
-0
autoload.php
vendor/perftools/php-profiler/examples/autoload.php
+135
-0
ProfilerException.php
...erftools/php-profiler/src/Exception/ProfilerException.php
+9
-0
Profiler.php
vendor/perftools/php-profiler/src/Profiler.php
+301
-0
ProfilerFactory.php
vendor/perftools/php-profiler/src/ProfilerFactory.php
+58
-0
AbstractProfiler.php
...perftools/php-profiler/src/Profilers/AbstractProfiler.php
+27
-0
ProfilerInterface.php
...erftools/php-profiler/src/Profilers/ProfilerInterface.php
+26
-0
Tideways.php
vendor/perftools/php-profiler/src/Profilers/Tideways.php
+40
-0
TidewaysXHProf.php
...r/perftools/php-profiler/src/Profilers/TidewaysXHProf.php
+43
-0
UProfiler.php
vendor/perftools/php-profiler/src/Profilers/UProfiler.php
+35
-0
XHProf.php
vendor/perftools/php-profiler/src/Profilers/XHProf.php
+48
-0
ProfilingData.php
vendor/perftools/php-profiler/src/ProfilingData.php
+122
-0
ProfilingFlags.php
vendor/perftools/php-profiler/src/ProfilingFlags.php
+11
-0
AbstractSaver.php
vendor/perftools/php-profiler/src/Saver/AbstractSaver.php
+20
-0
FileSaver.php
vendor/perftools/php-profiler/src/Saver/FileSaver.php
+26
-0
MongoSaver.php
vendor/perftools/php-profiler/src/Saver/MongoSaver.php
+54
-0
PdoSaver.php
vendor/perftools/php-profiler/src/Saver/PdoSaver.php
+27
-0
SaverInterface.php
vendor/perftools/php-profiler/src/Saver/SaverInterface.php
+16
-0
StackSaver.php
vendor/perftools/php-profiler/src/Saver/StackSaver.php
+68
-0
UploadSaver.php
vendor/perftools/php-profiler/src/Saver/UploadSaver.php
+83
-0
SaverFactory.php
vendor/perftools/php-profiler/src/SaverFactory.php
+129
-0
No files found.
application/exception/custom/GoodsException.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Exception\custom
;
use
App\Exception\BaseException
;
class
GoodsException
extends
BaseException
{
protected
$base_code
=
Code
::
GOODS
;
protected
$cus
=
[
0
=>
'商品创建失败,请稍后重试'
,
1
=>
'店铺ID创建失败'
,
2
=>
'商品ID创建失败'
,
3
=>
'门店ID创建失败'
,
4
=>
'门店名字不能重复'
,
5
=>
'套餐编辑失败,请稍后重试'
,
6
=>
'套餐ID创建失败'
,
7
=>
'套餐名字不能重复'
,
8
=>
'套餐数据不全'
,
9
=>
'审核驳回时,驳回原因不能为空'
,
10
=>
'当前商品已经审核过了,不需要重复审核'
,
11
=>
'审核商品失败'
,
12
=>
'审核状态错误'
,
13
=>
'无权限操作'
,
];
}
\ No newline at end of file
application/library/Validate/EditSetmealValidate.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Validate
;
/**
* Class EditSetmealValidate
*
* @package Validate
*/
class
EditSetmealValidate
extends
BaseValidate
{
protected
$rule
=
[
'life_account_id'
=>
'require'
,
'good_sku_id'
=>
'require'
,
'setmeal_data'
=>
'require'
,
];
protected
$message
=
[
"life_account_id"
=>
"生活号id不能为空"
,
"good_sku_id"
=>
"商品id不能为空"
,
"setmeal_data"
=>
"套餐数据不能为空"
,
];
}
\ No newline at end of file
application/library/Validate/EditStoresValidate.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Validate
;
/**
* Class EditStoresValidate
*
* @package Validate
*/
class
EditStoresValidate
extends
BaseValidate
{
protected
$rule
=
[
'life_account_id'
=>
'require'
,
'name'
=>
'require'
,
'address_lng'
=>
'require'
,
'address_lat'
=>
'require'
,
'address'
=>
'require'
,
'phone'
=>
'require'
,
];
protected
$message
=
[
"life_account_id"
=>
"生活号id不能为空"
,
"name"
=>
"门店名称不能为空"
,
"address_lng"
=>
"门店位置经度不能为空"
,
"address_lat"
=>
"门店位置纬度不能为空"
,
"address"
=>
"门店地址不能为空"
,
"phone"
=>
"门店电话不能为空"
,
];
}
\ No newline at end of file
application/library/Validate/GoodsAuditValidate.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Validate
;
/**
* Class GoodsAuditValidate
*
* @package Validate
*/
class
GoodsAuditValidate
extends
BaseValidate
{
protected
$rule
=
[
'goods_spu_id'
=>
'require'
,
'status'
=>
'require'
,
'uid'
=>
'require'
,
'username'
=>
'require'
,
];
protected
$message
=
[
"goods_spu_id"
=>
"商品id不能为空"
,
"status"
=>
"商品状态不能为空"
,
"uid"
=>
"用户id不能为空"
,
"username"
=>
"用户username不能为空"
,
];
}
\ No newline at end of file
application/library/Validate/SetmealListValidate.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Validate
;
/**
* Class SetmealListValidate
*
* @package Validate
*/
class
SetmealListValidate
extends
BaseValidate
{
protected
$rule
=
[
'goods_sku_id'
=>
'require'
,
];
protected
$message
=
[
"goods_sku_id"
=>
"商品id不能为空"
,
];
}
\ No newline at end of file
application/library/Validate/StoresListValidate.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Validate
;
/**
* Class StoresListValidate
*
* @package Validate
*/
class
StoresListValidate
extends
BaseValidate
{
protected
$rule
=
[
'life_account_id'
=>
'require'
,
];
protected
$message
=
[
"life_account_id"
=>
"生活号id不能为空"
,
];
}
\ No newline at end of file
application/models/goods/mysql/Category.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class Category
* 商品分类
* @package App\Models\goods\mysql
*/
class
Category
extends
MysqlBase
{
const
TABLE_NAME
=
'category'
;
const
CONFIG_INDEX
=
'goods'
;
const
LEVEL_1
=
1
;
const
LEVEL_2
=
2
;
public
static
function
getRecordList
(
$where
=
[],
$columns
=
[])
{
if
(
empty
(
$columns
))
{
$columns
=
'*'
;
}
return
self
::
select
(
$columns
,
$where
);
}
}
\ No newline at end of file
application/models/goods/mysql/GoodsOperationRecord.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class GoodsOperationRecord
* 商品操作记录
* @package App\Models\goods\mysql
*/
class
GoodsOperationRecord
extends
MysqlBase
{
const
TABLE_NAME
=
'goods_operation_record'
;
const
CONFIG_INDEX
=
'goods'
;
const
STATUS_AUDIT
=
0
;
//待审核
const
STATUS_PASS
=
1
;
//审核通过
const
STATUS_REJECT
=
2
;
//审核驳回
const
ONLINE_STATUS_ONLINE
=
1
;
//已上架
const
ONLINE_STATUS_OFFLINE
=
2
;
//已下架
public
static
function
getRecord
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
get
(
$colums
,
$where
);
}
public
static
function
insertRecord
(
$colums
)
{
return
self
::
insert
(
$colums
);
}
}
\ No newline at end of file
application/models/goods/mysql/GoodsSku.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class GoodsSku
* 商品sku信息
* @package App\Models\goods\mysql
*/
class
GoodsSku
extends
MysqlBase
{
const
TABLE_NAME
=
'goods_sku'
;
const
CONFIG_INDEX
=
'goods'
;
const
STATUS_AUDIT
=
0
;
//待审核
const
STATUS_PASS
=
1
;
//审核通过
const
STATUS_REJECT
=
2
;
//审核驳回
const
ONLINE_STATUS_ONLINE
=
1
;
//已上架
const
ONLINE_STATUS_OFFLINE
=
2
;
//已下架
public
static
function
getRecord
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
get
(
$colums
,
$where
);
}
public
static
function
getRecordMaster
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
selectMaster
(
$colums
,
$where
);
}
public
static
function
save
(
$data
,
$where
=
[])
{
if
(
empty
(
$where
))
{
return
self
::
insert
(
$data
);
}
return
self
::
update
(
$data
,
$where
);
}
public
static
function
deleteRecord
(
$where
)
{
return
self
::
delete
(
$where
);
}
}
\ No newline at end of file
application/models/goods/mysql/GoodsSkuStores.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class GoodsSkuStores
* 商品门店关系
* @package App\Models\goods\mysql
*/
class
GoodsSkuStores
extends
MysqlBase
{
const
TABLE_NAME
=
'goods_sku_stores'
;
const
CONFIG_INDEX
=
'goods'
;
public
static
function
getRecord
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
get
(
$colums
,
$where
);
}
public
static
function
getRecordMaster
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
selectMaster
(
$colums
,
$where
);
}
public
static
function
save
(
$data
,
$where
=
[])
{
if
(
empty
(
$where
))
{
return
self
::
insert
(
$data
);
}
return
self
::
update
(
$data
,
$where
);
}
public
static
function
deleteRecord
(
$where
)
{
return
self
::
delete
(
$where
);
}
}
\ No newline at end of file
application/models/goods/mysql/GoodsSnapshot.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class GoodsSnapshot
* 商品快照
* @package App\Models\goods\mysql
*/
class
GoodsSnapshot
extends
MysqlBase
{
const
TABLE_NAME
=
'goods_snapshot'
;
const
CONFIG_INDEX
=
'goods'
;
public
static
function
getRecord
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
get
(
$colums
,
$where
);
}
public
static
function
getRecordMaster
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
selectMaster
(
$colums
,
$where
);
}
public
static
function
insertRecord
(
$colums
)
{
return
self
::
insert
(
$colums
);
}
}
\ No newline at end of file
application/models/goods/mysql/GoodsSpu.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class GoodsSpu
* 商品spu信息
* @package App\Models\goods\mysql
*/
class
GoodsSpu
extends
MysqlBase
{
const
TABLE_NAME
=
'goods_spu'
;
const
CONFIG_INDEX
=
'goods'
;
public
static
function
getRecord
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
get
(
$colums
,
$where
);
}
public
static
function
getRecordMaster
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
selectMaster
(
$colums
,
$where
);
}
public
static
function
insertRecord
(
$colums
)
{
return
self
::
insert
(
$colums
);
}
public
static
function
updateRecord
(
$colums
,
$where
)
{
return
self
::
update
(
$colums
,
$where
);
}
public
static
function
save
(
$data
,
$where
=
[])
{
if
(
empty
(
$where
))
{
return
self
::
insert
(
$data
);
}
return
self
::
update
(
$data
,
$where
);
}
public
static
function
deleteRecord
(
$where
)
{
return
self
::
delete
(
$where
);
}
}
\ No newline at end of file
application/models/goods/mysql/InventoryOperationRecord.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class InventoryOperationRecord
* 库存操作记录
* @package App\Models\goods\mysql
*/
class
InventoryOperationRecord
extends
MysqlBase
{
const
TABLE_NAME
=
'inventory_operation_record'
;
const
CONFIG_INDEX
=
'goods'
;
public
static
function
getRecord
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
get
(
$colums
,
$where
);
}
public
static
function
getRecordMaster
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
selectMaster
(
$colums
,
$where
);
}
public
static
function
insertRecord
(
$colums
)
{
return
self
::
insert
(
$colums
);
}
}
\ No newline at end of file
application/models/goods/mysql/Setmeal.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class Setmeal
* 套餐
* @package App\Models\goods\mysql
*/
class
Setmeal
extends
MysqlBase
{
const
TABLE_NAME
=
'setmeal'
;
const
CONFIG_INDEX
=
'goods'
;
public
static
function
getRecord
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
get
(
$colums
,
$where
);
}
public
static
function
getRecordMaster
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
selectMaster
(
$colums
,
$where
);
}
public
static
function
save
(
$data
,
$where
=
[])
{
if
(
empty
(
$where
))
{
return
self
::
insert
(
$data
);
}
return
self
::
update
(
$data
,
$where
);
}
public
static
function
deleteRecord
(
$where
)
{
return
self
::
delete
(
$where
);
}
public
static
function
getAll
(
$goodsSkuId
)
{
return
self
::
select
(
'*'
,
[
'goods_sku_id'
=>
$goodsSkuId
]);
}
}
\ No newline at end of file
application/models/goods/mysql/Shop.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class Shop
* 店铺
* @package App\Models\goods\mysql
*/
class
Shop
extends
MysqlBase
{
const
TABLE_NAME
=
'shop'
;
const
CONFIG_INDEX
=
'goods'
;
const
STATUS_ONLINE
=
1
;
// 上线
const
STATUS_OFFLINE
=
2
;
// 下线
public
static
function
getRecord
(
$where
,
$columns
=
[])
{
if
(
empty
(
$columns
))
{
$columns
=
'*'
;
}
return
self
::
get
(
$columns
,
$where
);
}
public
static
function
getRecordMaster
(
$where
,
$columns
=
[])
{
if
(
empty
(
$columns
))
{
$columns
=
'*'
;
}
return
self
::
selectMaster
(
$columns
,
$where
);
}
public
static
function
save
(
$data
,
$where
=
[])
{
if
(
empty
(
$where
))
{
return
self
::
insert
(
$data
);
}
return
self
::
update
(
$data
,
$where
);
}
public
static
function
deleteRecord
(
$where
)
{
return
self
::
delete
(
$where
);
}
}
\ No newline at end of file
application/models/goods/mysql/Stores.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Models\goods\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
/**
* Class Stores
* 门店
* @package App\Models\goods\mysql
*/
class
Stores
extends
MysqlBase
{
const
TABLE_NAME
=
'stores'
;
const
CONFIG_INDEX
=
'goods'
;
public
static
function
getRecord
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
get
(
$colums
,
$where
);
}
public
static
function
getRecordMaster
(
$where
,
$colums
=
[])
{
if
(
empty
(
$colums
))
{
$colums
=
'*'
;
}
return
self
::
selectMaster
(
$colums
,
$where
);
}
public
static
function
save
(
$data
,
$where
=
[])
{
if
(
empty
(
$where
))
{
return
self
::
insert
(
$data
);
}
return
self
::
update
(
$data
,
$where
);
}
public
static
function
deleteRecord
(
$where
)
{
return
self
::
delete
(
$where
);
}
public
static
function
getAll
(
$lifeAccountId
)
{
return
self
::
select
(
'*'
,
[
'life_account_id'
=>
$lifeAccountId
]);
}
}
\ No newline at end of file
application/modules/Goods/controllers/Goods.php
0 → 100644
View file @
7b4d4a9f
<?php
use
App\Base\Base
;
use
App\Services\goods\GoodsService
;
use
App\Services\goods\CategoryService
;
use
App\Services\goods\StoresService
;
use
App\Services\goods\SetmealService
;
use
\Validate\EditStoresValidate
;
use
\Validate\StoresListValidate
;
use
\Validate\EditSetmealValidate
;
use
\Validate\SetmealListValidate
;
use
\Validate\GoodsAuditValidate
;
class
GoodsController
extends
Base
{
/**
* 获取商品分类列表
*/
public
function
get_goods_category_listAction
()
{
$categoryList
=
CategoryService
::
getCategoryList
();
$this
->
success
([
"data"
=>
$categoryList
]);
}
/**
* 增加商品
*/
public
function
addAction
()
{
$lifeAccountId
=
111
;
$params
=
[
"name"
=>
"商品name"
,
"url"
=>
"url1, url2, url3"
,
"desc"
=>
"描述描述"
,
"category_1_id"
=>
1
,
"category_2_id"
=>
13
,
"expiration_time"
=>
"2021-06-10 12:20:30"
,
"rule_limit"
=>
3
,
"rule_date_type"
=>
1
,
"rule_start_time"
=>
"2021-06-11 12:20:30"
,
"rule_end_time"
=>
"2021-06-12 12:20:30"
,
"rule_desc"
=>
"规则描述"
,
"inventory_total"
=>
10
,
"original_price"
=>
1500
,
"price"
=>
500
,
];
GoodsService
::
addGoods
(
$lifeAccountId
,
$params
);
$this
->
success
();
}
/**
* 编辑商品
*/
public
function
editAction
()
{
}
/**
* 商品详情
*/
public
function
infoAction
()
{
}
/**
* 上下架
*/
public
function
online_offlineAction
()
{
}
/**
* 审核通过/驳回
*/
public
function
auditAction
()
{
(
new
GoodsAuditValidate
())
->
validate
();
$params
=
$this
->
params
;
GoodsService
::
audit
(
$params
);
$this
->
success
();
}
/**
* 判断商品名称是否可用
*/
public
function
check_goods_nameAction
()
{
}
/**
* 套餐列表
* todo::可能会去掉
*/
public
function
setmeal_listAction
()
{
(
new
SetmealListValidate
())
->
validate
();
$params
=
$this
->
params
;
$goodSkuId
=
$params
[
"goods_sku_id"
];
$list
=
SetmealService
::
getSetmealList
(
$goodSkuId
);
$this
->
success
([
"data"
=>
$list
]);
}
/**
* 编辑套餐, 只支持编辑,不支持增加(因为增加时候还没有skuid)
* 这里套餐能一次传多个过来,这里按套餐数组处理
*/
public
function
edit_setmealAction
()
{
(
new
EditSetmealValidate
())
->
validate
();
$params
=
$this
->
params
;
SetmealService
::
editSetmeal
(
$params
);
$this
->
success
();
}
/**
* 门店列表
* @throws \App\Exception\custom\ParamException
*/
public
function
stores_listAction
()
{
(
new
StoresListValidate
())
->
validate
();
$params
=
$this
->
params
;
$lifeAccountId
=
$params
[
"life_account_id"
];
$list
=
StoresService
::
getStoresList
(
$lifeAccountId
);
$this
->
success
([
"data"
=>
$list
]);
}
/**
* 编辑门店
*/
public
function
edit_storesAction
()
{
(
new
EditStoresValidate
())
->
validate
();
$params
=
$this
->
params
;
StoresService
::
editStores
(
$params
);
$this
->
success
();
}
/**
* op后台:商品列表 (spu list)
*/
public
function
goods_list_opAction
()
{
}
/**
* b端:商品列表(spu list)
*/
public
function
goods_list_bAction
()
{
}
/**
* c端 es:商品列表 (sku list)
*/
public
function
goods_list_cAction
()
{
}
}
\ No newline at end of file
application/services/goods/CategoryService.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Services\goods
;
use
App\Models\goods\mysql\Category
;
class
CategoryService
{
public
static
function
getCategoryList
()
{
//todo::加上redis
$allCaregoryList
=
Category
::
getRecordList
([],
[
'category_id'
,
'parent_category_id'
,
'name'
,
'level'
]);
$data
=
[];
if
(
!
empty
(
$allCaregoryList
))
{
foreach
(
$allCaregoryList
as
$caregory
)
{
if
(
$caregory
[
"level"
]
==
Category
::
LEVEL_1
)
{
$data
[
"level_1"
][]
=
[
"category_id"
=>
$caregory
[
"category_id"
],
"name"
=>
$caregory
[
"name"
]
];
}
if
(
$caregory
[
"level"
]
==
Category
::
LEVEL_2
)
{
$data
[
"level_2"
][
$caregory
[
"parent_category_id"
]][]
=
[
"category_id"
=>
$caregory
[
"category_id"
],
"name"
=>
$caregory
[
"name"
]
];
}
}
}
return
$data
;
}
}
\ No newline at end of file
application/services/goods/GoodsService.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Services\goods
;
use
Api\PhpServices\Idgen\Idgen
;
use
App\Exception\custom\GoodsException
;
use
App\Models\goods\mysql\GoodsOperationRecord
;
use
App\Models\goods\mysql\GoodsSku
;
use
App\Models\goods\mysql\GoodsSpu
;
use
App\Models\goods\mysql\Shop
;
class
GoodsService
{
/**
* 通过发号器拿 id (非雪花)
* number,获取店铺shop_id用生活号id后两位,商品相关的这里是shop_id的后两位
* @param $number
* @param $type
* @param int $count
* @return array|mixed
*/
public
static
function
getIdgenId
(
$number
,
$type
,
$count
=
1
)
{
$res
=
Idgen
::
get
(
appConfig
(
'idgen.partner'
),
appConfig
(
'idgen.key'
),
[],
[[
"type"
=>
$type
,
'number'
=>
(
int
)
$number
,
"count"
=>
$count
]]);
return
$res
[
'id_datetime'
][
$type
]
??
[];
}
public
static
function
getSnowIdgenId
(
$type
,
$count
=
1
)
{
$res
=
Idgen
::
get
(
appConfig
(
'idgen.partner'
),
appConfig
(
'idgen.key'
),
[[
"type"
=>
$type
,
"count"
=>
$count
]],
[]);
return
$res
[
'id_snow'
][
$type
]
??
[];
}
/**
* 添加商品
* @param $lifeAccountId
* @param array $params
* @return mixed
* @throws GoodsException
*/
public
static
function
addGoods
(
$lifeAccountId
,
$params
=
[])
{
//todo:: 获取 $lifeAccount信息
$lifeAccount
=
[
"life_account_id"
=>
111
,
"merchant_id"
=>
1
,
"life_account_name"
=>
"测试测试"
,
];
GoodsSpu
::
beginTransaction
();
$shopId
=
self
::
addShop
(
$lifeAccount
);
$spuData
=
[
"name"
=>
$params
[
"name"
],
"url"
=>
$params
[
"url"
],
"desc"
=>
$params
[
"desc"
],
];
$spuId
=
self
::
addGoodsSpu
(
$shopId
,
$spuData
);
$skuId
=
self
::
addGoodsSku
(
$spuId
,
$shopId
,
$lifeAccountId
,
$params
);
if
(
!
GoodsSpu
::
commit
())
{
GoodsSpu
::
rollback
();
throw
new
GoodsException
([
"cus"
=>
0
]);
}
return
$skuId
;
}
/**
* 添加spu
* @param $shopId
* @param array $spuData
* @return mixed
* @throws GoodsException
*/
private
static
function
addGoodsSpu
(
$shopId
,
$spuData
=
[])
{
$res
=
self
::
getIdgenId
(
substr
(
$shopId
,
-
2
),
"goods"
);
if
(
empty
(
$res
))
{
throw
new
GoodsException
([
'cus'
=>
2
]);
}
$spuId
=
$res
[
0
];
GoodsSpu
::
save
([
"goods_spu_id"
=>
$spuId
,
"shop_id"
=>
$shopId
,
"name"
=>
$spuData
[
"name"
],
"url"
=>
$spuData
[
"url"
],
"desc"
=>
$spuData
[
"desc"
],
]);
return
$spuId
;
}
/**
* 添加sku
* @param $spuId
* @param $shopId
* @param $lifeAccountId
* @param array $skuData
* @return mixed
* @throws GoodsException
*/
private
static
function
addGoodsSku
(
$spuId
,
$shopId
,
$lifeAccountId
,
$skuData
=
[])
{
$res
=
self
::
getIdgenId
(
substr
(
$shopId
,
-
2
),
"goods"
);
if
(
empty
(
$res
))
{
throw
new
GoodsException
([
'cus'
=>
2
]);
}
$skuId
=
$res
[
0
];
GoodsSku
::
save
([
"goods_spu_id"
=>
$spuId
,
"goods_sku_id"
=>
$skuId
,
"shop_id"
=>
$shopId
,
"life_account_id"
=>
$lifeAccountId
,
"category_1_id"
=>
$skuData
[
"category_1_id"
],
"category_2_id"
=>
$skuData
[
"category_2_id"
],
"name"
=>
$skuData
[
"name"
],
"url"
=>
$skuData
[
"url"
],
"desc"
=>
$skuData
[
"desc"
],
"expiration_time"
=>
$skuData
[
"expiration_time"
],
"rule_limit"
=>
$skuData
[
"rule_limit"
],
"rule_date_type"
=>
$skuData
[
"rule_date_type"
],
"rule_start_time"
=>
$skuData
[
"rule_start_time"
],
"rule_end_time"
=>
$skuData
[
"rule_end_time"
],
"rule_desc"
=>
$skuData
[
"rule_desc"
],
"inventory_total"
=>
$skuData
[
"inventory_total"
],
"original_price"
=>
$skuData
[
"original_price"
],
"price"
=>
$skuData
[
"price"
],
]);
return
$skuId
;
}
/**
* 添加商铺
* @param $lifeAccount
* @return mixed
* @throws GoodsException
*/
private
static
function
addShop
(
$lifeAccount
)
{
$lifeAccountId
=
$lifeAccount
[
"life_account_id"
];
$shop
=
Shop
::
getRecordMaster
([
'life_account_id'
=>
$lifeAccountId
]);
if
(
empty
(
$shop
))
{
$res
=
self
::
getIdgenId
(
substr
(
$lifeAccountId
,
-
2
),
"goods"
);
if
(
empty
(
$res
))
{
throw
new
GoodsException
([
'cus'
=>
1
]);
}
$shopId
=
$res
[
0
];
Shop
::
save
([
"shop_id"
=>
$shopId
,
"life_account_id"
=>
$lifeAccountId
,
"merchant_id"
=>
$lifeAccount
[
"merchant_id"
],
"name"
=>
$lifeAccount
[
"life_account_name"
],
"status"
=>
Shop
::
STATUS_ONLINE
,
]);
}
else
{
$shopId
=
$shop
[
0
][
"shop_id"
];
}
return
$shopId
;
}
/**
* 审核
* @param array $params
* @return bool
* @throws GoodsException
*/
public
static
function
audit
(
$params
=
[])
{
$goodsSpuId
=
$params
[
"goods_spu_id"
];
$status
=
$params
[
"status"
];
$operatorId
=
$params
[
"uid"
];
$operatorName
=
$params
[
"username"
];
$goodsSpu
=
GoodsSpu
::
get
(
"*"
,
[
"goods_spu_id"
=>
$goodsSpuId
]);
//todo::权限判断 商品所属 life_account_id 或者 后台管理员
//权限判断
if
(
!
empty
(
$params
[
"life_account_id"
])
&&
$goodsSpu
[
"life_account_id"
]
!=
$params
[
"life_account_id"
])
{
throw
new
GoodsException
([
"cus"
=>
13
]);
}
//审核状态是否正确
if
(
!
in_array
(
$status
,
[
GoodsSku
::
STATUS_PASS
,
GoodsSku
::
STATUS_REJECT
]))
{
throw
new
GoodsException
([
"cus"
=>
12
]);
}
//驳回时候要有原因
if
(
$status
==
GoodsSku
::
STATUS_REJECT
&&
empty
(
$params
[
"rejected_reason"
]))
{
throw
new
GoodsException
([
"cus"
=>
9
]);
}
GoodsSku
::
beginTransaction
();
$goodsSkuList
=
GoodsSku
::
select
(
"*"
,
[
"goods_spu_id"
=>
$goodsSpuId
]);
if
(
!
empty
(
$goodsSkuList
))
{
foreach
(
$goodsSkuList
as
$sku
)
{
if
(
$sku
[
"status"
]
==
GoodsSku
::
STATUS_PASS
||
$sku
[
"status"
]
==
GoodsSku
::
STATUS_REJECT
)
{
throw
new
GoodsException
([
"cus"
=>
10
]);
}
$goodsSkuId
=
$sku
[
"goods_sku_id"
];
GoodsSku
::
save
([
"status"
=>
$status
],
[
"goods_sku_id"
=>
$sku
[
"goods_sku_id"
]]);
//todo:: info to es
//商品操作记录
$res
=
self
::
getSnowIdgenId
(
"goods"
);
if
(
empty
(
$res
))
{
throw
new
GoodsException
([
'cus'
=>
2
]);
}
$record
=
[
"goods_operation_record_id"
=>
$res
[
0
],
"goods_spu_id"
=>
$goodsSpuId
,
"goods_sku_id"
=>
$goodsSkuId
,
"operator_id"
=>
$operatorId
,
"operator_name"
=>
$operatorName
,
"goods_status"
=>
$status
,
"online_status"
=>
$sku
[
"online_status"
],
"before_version"
=>
$sku
[
"version"
],
"after_version"
=>
$sku
[
"version"
],
"note"
=>
empty
(
$params
[
"rejected_reason"
])
?
""
:
$params
[
"rejected_reason"
],
];
GoodsOperationRecord
::
insertRecord
(
$record
);
}
}
if
(
!
GoodsSku
::
commit
())
{
GoodsSku
::
rollback
();
throw
new
GoodsException
([
"cus"
=>
11
]);
}
return
true
;
}
public
static
function
checkGoodsName
(
$goodsName
)
{
}
}
\ No newline at end of file
application/services/goods/SetmealService.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Services\goods
;
use
App\Exception\custom\GoodsException
;
use
App\Models\goods\mysql\GoodsSpu
;
use
App\Models\goods\mysql\Setmeal
;
use
App\Models\goods\mysql\Stores
;
class
SetmealService
{
/**
* @param array $params
* 编辑套餐
* @return \Api\PhpUtils\Mysql\MysqlBase
* @throws GoodsException
*/
public
static
function
editSetmeal
(
$params
=
[])
{
$lifeAccountId
=
$params
[
"life_account_id"
];
$goodsSkuId
=
$params
[
"good_sku_id"
];
$setmealData
=
json_decode
(
$params
[
'setmeal_data'
],
true
);
Setmeal
::
beginTransaction
();
$updateData
=
$insertData
=
[];
foreach
(
$setmealData
as
$key
=>
$setmeal
)
{
if
(
empty
(
$setmeal
[
"name"
])
||
empty
(
$setmeal
[
"unit"
])
||
empty
(
$setmeal
[
"unit_number"
])
||
empty
(
$setmeal
[
"unit_price"
]))
{
throw
new
GoodsException
([
'cus'
=>
8
]);
}
if
(
!
empty
(
$setmeal
[
"setmeal_id"
]))
{
$updateData
[]
=
[
'setmeal_id'
=>
$setmeal
[
"setmeal_id"
],
'life_account_id'
=>
$lifeAccountId
,
'goods_sku_id'
=>
$goodsSkuId
,
'name'
=>
$setmeal
[
"name"
],
'unit'
=>
$setmeal
[
"unit"
],
'unit_number'
=>
$setmeal
[
"unit_number"
],
'unit_price'
=>
$setmeal
[
"unit_price"
]
*
100
,
];
}
else
{
$insertData
[]
=
[
'life_account_id'
=>
$lifeAccountId
,
'goods_sku_id'
=>
$goodsSkuId
,
'name'
=>
$setmeal
[
"name"
],
'unit'
=>
$setmeal
[
"unit"
],
'unit_number'
=>
$setmeal
[
"unit_number"
],
'unit_price'
=>
$setmeal
[
"unit_price"
]
*
100
,
];
}
}
if
(
!
empty
(
$insertData
))
{
$ids
=
GoodsService
::
getIdgenId
(
substr
(
$lifeAccountId
,
-
2
),
"goods"
,
count
(
$insertData
));
if
(
empty
(
$ids
))
{
throw
new
GoodsException
([
'cus'
=>
6
]);
}
foreach
(
$insertData
as
$insertKey
=>
$item
)
{
//判断重复
$setmeal
=
Setmeal
::
getRecordMaster
([
"goods_sku_id"
=>
$goodsSkuId
,
"name"
=>
$item
[
"name"
]]);
if
(
!
empty
(
$setmeal
))
{
throw
new
GoodsException
([
'cus'
=>
7
]);
}
$item
[
"setmeal_id"
]
=
$ids
[
$insertKey
];
Setmeal
::
save
(
$item
);
}
}
if
(
!
empty
(
$updateData
))
{
foreach
(
$updateData
as
$item
)
{
//todo::update去重
$where
=
[];
$where
[
"setmeal_id"
]
=
$item
[
"setmeal_id"
];
unset
(
$item
[
"setmeal_id"
]);
Setmeal
::
save
(
$item
,
$where
);
}
}
if
(
!
Setmeal
::
commit
())
{
Setmeal
::
rollback
();
throw
new
GoodsException
([
"cus"
=>
5
]);
}
}
/**
* @param $goodSkuId
* @return \Api\PhpUtils\Mysql\MysqlBase
*/
public
static
function
getSetmealList
(
$goodSkuId
)
{
$list
=
Setmeal
::
getAll
(
$goodSkuId
);
if
(
!
empty
(
$list
))
{
foreach
(
$list
as
$key
=>
$item
)
{
$list
[
$key
][
"unit_price"
]
=
$item
[
"unit_price"
]
/
100
;
}
}
return
$list
;
}
}
\ No newline at end of file
application/services/goods/StoresService.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
App\Services\goods
;
use
App\Exception\custom\GoodsException
;
use
App\Models\goods\mysql\Stores
;
class
StoresService
{
/**
* @param array $params
* 编辑门店
* @return \Api\PhpUtils\Mysql\MysqlBase
* @throws GoodsException
*/
public
static
function
editStores
(
$params
=
[])
{
$data
=
$where
=
[];
$lifeAccountId
=
$params
[
"life_account_id"
];
$name
=
$params
[
"name"
];
if
(
!
empty
(
$params
[
"stores_id"
]))
{
$where
[
"stores_id"
]
=
$params
[
"stores_id"
];
}
else
{
$stores
=
Stores
::
getRecordMaster
([
"life_account_id"
=>
$lifeAccountId
,
"name"
=>
$name
]);
if
(
!
empty
(
$stores
))
{
throw
new
GoodsException
([
'cus'
=>
4
]);
}
$res
=
GoodsService
::
getIdgenId
(
substr
(
$lifeAccountId
,
-
2
),
"goods"
);
if
(
empty
(
$res
))
{
throw
new
GoodsException
([
'cus'
=>
3
]);
}
$data
[
"stores_id"
]
=
$res
[
"0"
];
}
$data
[
"name"
]
=
$name
;
$data
[
"address_lng"
]
=
$params
[
"address_lng"
];
$data
[
"address_lat"
]
=
$params
[
"address_lat"
];
$data
[
"address"
]
=
$params
[
"address"
];
$data
[
"phone"
]
=
$params
[
"phone"
];
$data
[
"life_account_id"
]
=
$params
[
"life_account_id"
];
return
Stores
::
save
(
$data
,
$where
);
}
/**
* @param $lifeAccountId
* @return \Api\PhpUtils\Mysql\MysqlBase
*/
public
static
function
getStoresList
(
$lifeAccountId
)
{
return
Stores
::
getAll
(
$lifeAccountId
);
}
}
\ No newline at end of file
vendor/api/php_services/src/XhProfiler/XhMongo.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Api\PhpServices\XhProfiler
;
use
Api\PhpUtils\Mongo\MongoBase
;
class
XhMongo
extends
MongoBase
{
private
$domian
;
public
function
__construct
(
$domain
)
{
$this
->
domian
=
$domain
;
}
protected
function
getConfigIndex
()
{
//需要在yaconf 配置 mongo
return
'xhprof'
;
}
protected
function
getDatabaseName
()
{
return
'xhprof'
;
}
protected
function
getCollectionName
()
{
// 根据 domain 来生成对应的collection
return
$this
->
domian
.
'_'
.
'xhprof'
;
}
}
\ No newline at end of file
vendor/api/php_services/src/XhProfiler/XhProfilerService.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Api\PhpServices\XhProfiler
;
use
Xhgui\Profiler\Profiler
;
class
XhProfilerService
{
private
$profiler
;
public
function
__construct
(
$domain
)
{
// 根据域名读取 配置
$this
->
profiler
=
new
Profiler
([]);
}
/**
* 开启 xhprofiler 分析
* @param $domain
*/
public
function
start
(
$domain
)
:
void
{
//根据域名选择开不开启 分析
if
(
$this
->
judgeSwitch
(
$domain
)
===
false
)
{
return
;
}
//开启 分析器,并且初始化 mongodb 实例
$this
->
profiler
->
start
();
}
/**
* 结束分析 并且 根据域名存储到不同的 mongodb collection 中
* @param $domain
*/
public
function
end
(
$domain
)
:
void
{
// 结束分析器,生产性能检测数据
$profiler_data
=
$this
->
profiler
->
disable
();
//将数据存储到 指定mongodb中
$mongo
=
new
XhMongo
(
'test'
);
$mongo
->
insertOne
(
$profiler_data
);
// $this->profiler->save($profiler_data);
}
/**
* 开关决策器
* @param $domain
* @return bool
*/
private
function
judgeSwitch
(
$domain
)
{
// 从 yaconf 获取配置 ,判断当前域名是否要开启
return
true
;
}
}
\ No newline at end of file
vendor/api/php_utils/src/Ksy/Ks3Util.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Api\PhpUtils\Ksy
;
use
Api\PhpUtils\Http\Request
;
/**
* 金山云ks3相关
* 仅实现了签名及删除单个方法,其他未实现
* ks3直接访问地址: https://ks3-cn-beijing.ksyun.com/article-yidian/article/0JRvMeHk
*/
class
Ks3Util
{
const
KS3_BASE_URL
=
'ks3-cn-beijing.ksyun.com'
;
const
FALLBACK_BUIDLER_BUCKET
=
'article-yidian'
;
const
KS_DATE_SCHEME
=
'D, d M Y H:i:s \G\M\T'
;
const
KSYUN_SK
=
"OMw7UAOkrLVsRevuP44ctAlfzriDzUm9+JvOFoYuiSoLgaLJWi+kjUa+4G3EWXFakQ=="
;
const
KSYUN_AK
=
"AKLTnATdoXUnR72IDSGgN2WSOQ"
;
const
YIDIAN_PROXY
=
true
;
//删除fallback builder 对于ks3节点的文章
public
static
function
delete_doc
(
$docid
,
$timeout
=
1000
)
{
return
self
::
delete
(
self
::
FALLBACK_BUIDLER_BUCKET
,
'article/'
.
$docid
,
$timeout
);
}
public
static
function
put_object
(
$data
,
$bucket
,
$object_key
,
$timeout
=
1000
)
{
$url
=
self
::
get_url
(
$bucket
)
.
'/'
.
$object_key
;
$canonicalized_resource
=
self
::
get_canonicalized_resource
(
$bucket
,
$object_key
);
$headers
=
array
(
'Host'
=>
self
::
get_url
(
$bucket
),
'Date'
=>
gmdate
(
self
::
KS_DATE_SCHEME
),
'Content-Type'
=>
'multipart/form-data'
,
'Referer'
=>
$url
,
'x-kss-acl'
=>
'public-read'
,
//'Expect' => '100-continue',
);
$headers
[
'Authorization'
]
=
self
::
sign
(
'PUT'
,
$canonicalized_resource
,
$headers
);
foreach
(
$headers
as
$key
=>
$value
)
{
$header
[]
=
$key
.
':'
.
$value
;
}
$request
=
new
Request
();
$str
=
$request
->
uploadPut
(
$url
,
$data
,
$timeout
,
1
,
$header
,
self
::
YIDIAN_PROXY
);
return
$str
;
}
//查询文章在ks3是否存在,返回金山云返回的head http状态吗
public
static
function
exist
(
$bucket
,
$object_key
,
$timeout
=
1000
)
{
$url
=
self
::
get_url
(
$bucket
)
.
'/'
.
$object_key
;
$canonicalized_resource
=
self
::
get_canonicalized_resource
(
$bucket
,
$object_key
);
$headers
=
array
(
'Host'
=>
self
::
get_url
(
$bucket
),
'Date'
=>
gmdate
(
self
::
KS_DATE_SCHEME
),
'Content-Type'
=>
'application/xml'
,
);
$headers
[
'Authorization'
]
=
self
::
sign
(
'HEAD'
,
$canonicalized_resource
,
$headers
);
foreach
(
$headers
as
$key
=>
$value
)
{
$header
[]
=
$key
.
':'
.
$value
;
}
$request
=
new
Request
();
$str
=
$request
->
head
(
$url
,
$timeout
,
1
,
$header
,
self
::
YIDIAN_PROXY
);
return
$str
;
}
//删除ks3 节点指定bucket中的object
private
static
function
delete
(
$bucket
,
$object_key
,
$timeout
)
{
$url
=
self
::
get_url
(
$bucket
)
.
'/'
.
$object_key
;
$headers
=
array
(
'Host'
=>
self
::
get_url
(
$bucket
),
'Accept'
=>
'*/*'
,
'Accept-Encoding'
=>
'deflate, gzip'
,
'Referer'
=>
$url
,
'Content-Type'
=>
'application/xml'
,
'Date'
=>
gmdate
(
self
::
KS_DATE_SCHEME
),
'Content-Length'
=>
0
,
);
$canonicalized_resource
=
self
::
get_canonicalized_resource
(
$bucket
,
$object_key
);
$headers
[
'Authorization'
]
=
self
::
sign
(
'DELETE'
,
$canonicalized_resource
,
$headers
);
foreach
(
$headers
as
$key
=>
$value
)
{
$header
[]
=
$key
.
':'
.
$value
;
}
$request
=
new
Request
();
$str
=
$request
->
delete
(
$url
,
$timeout
,
1
,
$header
,
self
::
YIDIAN_PROXY
);
return
$str
;
}
private
static
function
get_url
(
$bucket
)
{
return
$bucket
.
'.'
.
self
::
KS3_BASE_URL
;
}
private
static
function
sign
(
$method
,
$canonicalized_resource
,
$headers
=
array
(),
$query
=
array
())
{
$canonicalized_kss_headers
=
self
::
format_headers
(
$headers
);
$tosign
=
$method
.
"
\n
"
.
''
.
"
\n
"
.
$headers
[
'Content-Type'
]
.
"
\n
"
.
$headers
[
'Date'
]
.
"
\n
"
.
$canonicalized_kss_headers
.
$canonicalized_resource
;
$signature
=
base64_encode
(
hash_hmac
(
'sha1'
,
$tosign
,
self
::
KSYUN_SK
,
true
));
$signature
=
'KSS '
.
self
::
KSYUN_AK
.
':'
.
$signature
;
return
$signature
;
}
//生成签名所需CanonicalizedKssHeaders,详见https://ks3.ksyun.com/doc/api/index.html
private
static
function
format_headers
(
array
$headers
)
{
if
(
empty
(
$headers
)
)
{
return
''
;
}
foreach
(
$headers
as
$key
=>
$header
)
{
if
(
substr
(
$key
,
0
,
6
)
==
'x-kss-'
)
{
$headers_to_sign
[
strtolower
(
$key
)]
=
$header
;
}
}
if
(
empty
(
$headers_to_sign
)
)
{
return
''
;
}
ksort
(
$headers_to_sign
);
$ret
=
''
;
foreach
(
$headers_to_sign
as
$key
=>
$value
)
{
$ret
=
$key
.
':'
.
$value
.
"
\n
"
;
}
return
$ret
;
}
//
private
static
function
get_canonicalized_resource
(
$bucket
,
$object_key
)
{
return
'/'
.
$bucket
.
'/'
.
$object_key
;
}
}
vendor/perftools/php-profiler/AUTHORS
0 → 100644
View file @
7b4d4a9f
Elan Ruusamäe <glen@pld-linux.org>
Lauri Piisang <lauri.piisang@eesti.ee>
vendor/perftools/php-profiler/LICENSE
0 → 100644
View file @
7b4d4a9f
MIT License
Copyright (c) 2017 Lauri Piisang
Copyright (c) 2019-2020 Elan Ruusamäe
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.
vendor/perftools/php-profiler/README.md
0 → 100644
View file @
7b4d4a9f
This diff is collapsed.
Click to expand it.
vendor/perftools/php-profiler/autoload.php
0 → 100644
View file @
7b4d4a9f
<?php
/**
* This loads all classes used by this project.
*/
require_once
__DIR__
.
'/src/Profilers/ProfilerInterface.php'
;
require_once
__DIR__
.
'/src/Saver/SaverInterface.php'
;
require_once
__DIR__
.
'/src/Exception/ProfilerException.php'
;
require_once
__DIR__
.
'/src/Profiler.php'
;
require_once
__DIR__
.
'/src/ProfilerFactory.php'
;
require_once
__DIR__
.
'/src/Profilers/AbstractProfiler.php'
;
require_once
__DIR__
.
'/src/Profilers/Tideways.php'
;
require_once
__DIR__
.
'/src/Profilers/TidewaysXHProf.php'
;
require_once
__DIR__
.
'/src/Profilers/UProfiler.php'
;
require_once
__DIR__
.
'/src/Profilers/XHProf.php'
;
require_once
__DIR__
.
'/src/ProfilingData.php'
;
require_once
__DIR__
.
'/src/ProfilingFlags.php'
;
require_once
__DIR__
.
'/src/Saver/AbstractSaver.php'
;
require_once
__DIR__
.
'/src/Saver/FileSaver.php'
;
require_once
__DIR__
.
'/src/Saver/MongoSaver.php'
;
require_once
__DIR__
.
'/src/Saver/PdoSaver.php'
;
require_once
__DIR__
.
'/src/Saver/StackSaver.php'
;
require_once
__DIR__
.
'/src/Saver/UploadSaver.php'
;
require_once
__DIR__
.
'/src/SaverFactory.php'
;
vendor/perftools/php-profiler/examples/autoload.php
0 → 100644
View file @
7b4d4a9f
<?php
/**
* Bootstrap for php-profiler. Copy and customize this file,
* include this file inside some bootstrapper or other "early central point in execution"
*
* Documentation:
* - https://github.com/perftools/php-profiler#create-profiler
* - https://github.com/perftools/php-profiler#config
*/
use
Xhgui\Profiler\Profiler
;
use
Xhgui\Profiler\ProfilingFlags
;
require
__DIR__
.
'/../vendor/autoload.php'
;
try
{
$config
=
array
(
// If defined, use specific profiler
// otherwise use any profiler that's found
'profiler'
=>
Profiler
::
PROFILER_TIDEWAYS_XHPROF
,
// This allows to configure, what profiling data to capture
'profiler.flags'
=>
array
(
ProfilingFlags
::
CPU
,
ProfilingFlags
::
MEMORY
,
ProfilingFlags
::
NO_BUILTINS
,
ProfilingFlags
::
NO_SPANS
,
),
// Saver to use.
// Please note that 'pdo' and 'mongo' savers are deprecated
// Prefer 'upload' or 'file' saver.
'save.handler'
=>
Profiler
::
SAVER_UPLOAD
,
// Saving profile data by upload is only recommended with HTTPS
// endpoints that have IP whitelists applied.
// https://github.com/perftools/php-profiler#upload-saver
'save.handler.upload'
=>
array
(
'url'
=>
'https://example.com/run/import'
,
// The timeout option is in seconds and defaults to 3 if unspecified.
'timeout'
=>
3
,
// the token must match 'upload.token' config in XHGui
'token'
=>
'token'
,
),
// https://github.com/perftools/php-profiler#file-saver
'save.handler.file'
=>
array
(
// Appends jsonlines formatted data to this path
'filename'
=>
'/tmp/xhgui.data.jsonl'
,
),
// https://github.com/perftools/php-profiler#stack-saver
'save.handler.stack'
=>
array
(
'savers'
=>
array
(
Profiler
::
SAVER_UPLOAD
,
Profiler
::
SAVER_FILE
,
),
// if saveAll=false, break the chain on successful save
'saveAll'
=>
false
,
),
// https://github.com/perftools/php-profiler#mongodb-saver
'save.handler.mongodb'
=>
array
(
'dsn'
=>
'mongodb://127.0.0.1:27017'
,
'database'
=>
'xhprof'
,
// Allows you to pass additional options like replicaSet to MongoClient.
// 'username', 'password' and 'db' (where the user is added)
'options'
=>
array
(),
// Allows you to pass driver options like ca_file to MongoClient
'driverOptions'
=>
array
(),
),
// https://github.com/perftools/php-profiler#pdo-saver
'save.handler.pdo'
=>
array
(
'dsn'
=>
'sqlite:/tmp/xhgui.sqlite3'
,
'user'
=>
null
,
'pass'
=>
null
,
'table'
=>
'results'
,
),
// Environment variables to exclude from profiling data
'profiler.exclude-env'
=>
array
(),
'profiler.options'
=>
array
(),
/**
* Determine whether the profiler should run.
* This default implementation just disables the profiler.
* Override this with your custom logic in your config
* @return bool
*/
'profiler.enable'
=>
function
()
{
return
true
;
},
/**
* Creates a simplified URL given a standard URL.
* Does the following transformations:
*
* - Remove numeric values after "=" in query string.
*
* @param string $url
* @return string
*/
'profiler.simple_url'
=>
function
(
$url
)
{
return
preg_replace
(
'/=\d+/'
,
''
,
$url
);
},
/**
* Enable this to clean up the url before submitting it to XHGui.
* This way it is possible to remove sensitive data or discard any other data.
*
* The URL argument is the `REQUEST_URI` or `argv` value.
*
* @param string $url
* @return string
*/
'profiler.replace_url'
=>
function
(
$url
)
{
return
str_replace
(
'token'
,
''
,
$url
);
},
);
/**
* The constructor will throw an exception if the environment
* isn't fit for profiling (extensions missing, other problems)
*/
$profiler
=
new
Profiler
(
$config
);
// The profiler itself checks whether it should be enabled
// for request (executes lambda function from config)
$profiler
->
start
();
}
catch
(
Exception
$e
)
{
// throw away or log error about profiling instantiation failure
error_log
(
$e
->
getMessage
());
}
vendor/perftools/php-profiler/src/Exception/ProfilerException.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Exception
;
use
RuntimeException
;
class
ProfilerException
extends
RuntimeException
{
}
vendor/perftools/php-profiler/src/Profiler.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler
;
use
Xhgui\Profiler\Exception\ProfilerException
;
use
Xhgui\Profiler\Profilers\ProfilerInterface
;
use
Xhgui\Profiler\Saver\SaverInterface
;
class
Profiler
{
const
SAVER_UPLOAD
=
'upload'
;
const
SAVER_FILE
=
'file'
;
const
SAVER_MONGODB
=
'mongodb'
;
const
SAVER_PDO
=
'pdo'
;
const
SAVER_STACK
=
'stack'
;
const
PROFILER_TIDEWAYS
=
'tideways'
;
const
PROFILER_TIDEWAYS_XHPROF
=
'tideways_xhprof'
;
const
PROFILER_UPROFILER
=
'uprofiler'
;
const
PROFILER_XHPROF
=
'xhprof'
;
/**
* Profiler configuration.
*
* @var array
*/
private
$config
;
/**
* @var SaverInterface
*/
private
$saveHandler
;
/**
* @var ProfilerInterface
*/
private
$profiler
;
/**
* Simple state variable to hold the value of 'Is the profiler running or not?'
*
* @var bool
*/
private
$running
;
/**
* If true, session is closed, buffers are flushed and fcgi request is finished on shutdown handler
* Disable this if this conflicts with your framework.
*
* @var bool
*/
private
$flush
;
/**
* Profiler constructor.
*
* @param array $config
*/
public
function
__construct
(
array
$config
)
{
$this
->
config
=
array_replace
(
$this
->
getDefaultConfig
(),
$config
);
}
/**
* Evaluate profiler.enable condition, and start profiling if that returned true.
*/
public
function
start
(
$flush
=
true
)
{
if
(
!
$this
->
shouldRun
())
{
return
;
}
$this
->
enable
();
$this
->
flush
=
$flush
;
// shutdown handler collects and stores the data.
$this
->
registerShutdownHandler
();
}
/**
* Stop profiling. Get currently collected data and save it
*/
public
function
stop
()
{
$data
=
$this
->
disable
();
$this
->
save
(
$data
);
return
$data
;
}
/**
* Enables profiling for the current request / CLI execution
*/
public
function
enable
(
$flags
=
null
,
$options
=
null
)
{
$this
->
running
=
false
;
// 'REQUEST_TIME_FLOAT' isn't available before 5.4.0
// https://www.php.net/manual/en/reserved.variables.server.php
if
(
!
isset
(
$_SERVER
[
'REQUEST_TIME_FLOAT'
]))
{
$_SERVER
[
'REQUEST_TIME_FLOAT'
]
=
microtime
(
true
);
}
$profiler
=
$this
->
getProfiler
();
if
(
!
$profiler
)
{
throw
new
ProfilerException
(
'Unable to create profiler: No suitable profiler found'
);
}
$saver
=
$this
->
getSaver
();
if
(
!
$saver
)
{
throw
new
ProfilerException
(
'Unable to create saver'
);
}
if
(
$flags
===
null
)
{
$flags
=
$this
->
config
[
'profiler.flags'
];
}
if
(
$options
===
null
)
{
$options
=
$this
->
config
[
'profiler.options'
];
}
$profiler
->
enable
(
$flags
,
$options
);
$this
->
running
=
true
;
}
/**
* Stop profiling. Return currently collected data
*
* @return array
*/
public
function
disable
()
{
if
(
!
$this
->
running
)
{
return
array
();
}
$profiler
=
$this
->
getProfiler
();
if
(
!
$profiler
)
{
// error for unable to create profiler already thrown in enable() method
// but this can also happen if methods are called out of sync
throw
new
ProfilerException
(
'Unable to create profiler: No suitable profiler found'
);
}
$profile
=
new
ProfilingData
(
$this
->
config
);
$this
->
running
=
false
;
return
$profile
->
getProfilingData
(
$profiler
->
disable
());
}
/**
* Saves collected profiling data
*
* @param array $data
*/
public
function
save
(
array
$data
=
array
())
{
if
(
!
$data
)
{
return
;
}
$saver
=
$this
->
getSaver
();
if
(
!
$saver
)
{
// error for unable to create saver already thrown in enable() method
// but this can also happen if methods are called out of sync
throw
new
ProfilerException
(
'Unable to create profiler: Unable to create saver'
);
}
$saver
->
save
(
$data
);
}
/**
* Tells, if profiler is running or not
*
* @return bool
*/
public
function
isRunning
()
{
return
$this
->
running
;
}
/**
* Returns value of `profiler.enable` function evaluation
*
* @return bool
*/
private
function
shouldRun
()
{
$closure
=
$this
->
config
[
'profiler.enable'
];
return
is_callable
(
$closure
)
?
$closure
()
:
false
;
}
/**
* Calls register_shutdown_function .
* Registers this class' shutDown method as the shutdown handler
*
* @see Profiler::shutDown
*/
private
function
registerShutdownHandler
()
{
// do not register shutdown function if the profiler isn't running
if
(
!
$this
->
running
)
{
return
;
}
register_shutdown_function
(
array
(
$this
,
'shutDown'
));
}
/**
* @internal
*/
public
function
shutDown
()
{
if
(
$this
->
flush
)
{
$this
->
flush
();
}
try
{
$this
->
stop
();
}
catch
(
ProfilerException
$e
)
{
return
;
}
}
private
function
flush
()
{
// ignore_user_abort(true) allows your PHP script to continue executing, even if the user has terminated their request.
// Further Reading: http://blog.preinheimer.com/index.php?/archives/248-When-does-a-user-abort.html
// flush() asks PHP to send any data remaining in the output buffers. This is normally done when the script completes, but
// since we're delaying that a bit by dealing with the xhprof stuff, we'll do it now to avoid making the user wait.
ignore_user_abort
(
true
);
if
(
function_exists
(
'session_write_close'
))
{
session_write_close
();
}
flush
();
if
(
function_exists
(
'fastcgi_finish_request'
))
{
fastcgi_finish_request
();
}
}
/**
* @return ProfilerInterface|null
*/
private
function
getProfiler
()
{
if
(
$this
->
profiler
===
null
)
{
$this
->
profiler
=
ProfilerFactory
::
create
(
$this
->
config
)
?:
false
;
}
return
$this
->
profiler
?:
null
;
}
/**
* @return SaverInterface|null
*/
private
function
getSaver
()
{
if
(
$this
->
saveHandler
===
null
)
{
$this
->
saveHandler
=
SaverFactory
::
create
(
$this
->
config
[
'save.handler'
],
$this
->
config
)
?:
false
;
}
return
$this
->
saveHandler
?:
null
;
}
/**
* @return array
*/
private
function
getDefaultConfig
()
{
return
array
(
'save.handler'
=>
Profiler
::
SAVER_STACK
,
'save.handler.stack'
=>
array
(
'savers'
=>
array
(
Profiler
::
SAVER_UPLOAD
,
Profiler
::
SAVER_FILE
,
),
'saveAll'
=>
false
,
),
'save.handler.file'
=>
array
(
'filename'
=>
sys_get_temp_dir
()
.
'/xhgui.data.jsonl'
,
),
'profiler.enable'
=>
function
()
{
return
true
;
},
'profiler.flags'
=>
array
(
ProfilingFlags
::
CPU
,
ProfilingFlags
::
MEMORY
,
ProfilingFlags
::
NO_BUILTINS
,
ProfilingFlags
::
NO_SPANS
,
),
'profiler.options'
=>
array
(),
'profiler.exclude-env'
=>
array
(),
'profiler.simple_url'
=>
function
(
$url
)
{
return
preg_replace
(
'/=\d+/'
,
''
,
$url
);
},
'profiler.replace_url'
=>
null
,
);
}
}
vendor/perftools/php-profiler/src/ProfilerFactory.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler
;
use
Xhgui\Profiler\Exception\ProfilerException
;
use
Xhgui\Profiler\Profilers\ProfilerInterface
;
final
class
ProfilerFactory
{
/**
* Creates Profiler instance that can be used.
*
* It returns first profiler, that is usable in testing them in this order:
* 2) tideways_xhprof
* 2) tideways
* 1) uprofiler
* 3) xhprof
*
* @return ProfilerInterface|null
*/
public
static
function
create
(
array
$config
)
{
$adapters
=
array
(
Profiler
::
PROFILER_TIDEWAYS_XHPROF
=>
function
()
{
return
new
Profilers\TidewaysXHProf
();
},
Profiler
::
PROFILER_TIDEWAYS
=>
function
()
{
return
new
Profilers\Tideways
();
},
Profiler
::
PROFILER_UPROFILER
=>
function
()
{
return
new
Profilers\UProfiler
();
},
Profiler
::
PROFILER_XHPROF
=>
function
()
{
return
new
Profilers\XHProf
();
},
);
if
(
isset
(
$config
[
'profiler'
]))
{
$profiler
=
$config
[
'profiler'
];
if
(
!
isset
(
$adapters
[
$profiler
]))
{
throw
new
ProfilerException
(
"Specified profiler '
$profiler
' is not supported"
);
}
$adapters
=
array
(
$profiler
=>
$adapters
[
$profiler
],
);
}
foreach
(
$adapters
as
$profiler
=>
$factory
)
{
$adapter
=
$factory
(
$config
);
if
(
$adapter
->
isSupported
())
{
return
$adapter
;
}
}
return
null
;
}
}
vendor/perftools/php-profiler/src/Profilers/AbstractProfiler.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Profilers
;
abstract
class
AbstractProfiler
implements
ProfilerInterface
{
/**
* Combines flags using "bitwise-OR".
*
* Map generic Profiler\ProfilingFlags to {SPECIFIC_PROFILER_NAME_HERE} implementation
*
* @param array $flags
* @param array $flagMap an array with the structure [generic_flag => specific_profiler_flag], e.g. [ProfilingFlags::CPU => XHPROF_FLAGS_CPU]
* @return int
*/
protected
function
combineFlags
(
array
$flags
,
array
$flagMap
)
{
$combinedFlag
=
0
;
foreach
(
$flags
as
$flag
)
{
$mappedFlag
=
array_key_exists
(
$flag
,
$flagMap
)
?
$flagMap
[
$flag
]
:
$flag
;
$combinedFlag
|=
$mappedFlag
;
}
return
$combinedFlag
;
}
}
vendor/perftools/php-profiler/src/Profilers/ProfilerInterface.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Profilers
;
interface
ProfilerInterface
{
/**
* @return bool
*/
public
function
isSupported
();
/**
* Enable profiling.
*
* @param array $flags
* @param array $options
*/
public
function
enable
(
$flags
=
array
(),
$options
=
array
());
/**
* Disable (stop) the profiler. Return the collected data.
*
* @return array
*/
public
function
disable
();
}
vendor/perftools/php-profiler/src/Profilers/Tideways.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Profilers
;
use
Xhgui\Profiler\ProfilingFlags
;
/**
* v4 (tideways)
*
* @see https://github.com/tideways/php-profiler-extension
*/
class
Tideways
extends
AbstractProfiler
{
const
EXTENSION_NAME
=
'tideways'
;
public
function
isSupported
()
{
return
extension_loaded
(
self
::
EXTENSION_NAME
);
}
public
function
enable
(
$flags
=
array
(),
$options
=
array
())
{
tideways_enable
(
$this
->
combineFlags
(
$flags
,
$this
->
getProfileFlagMap
()),
$options
);
}
public
function
disable
()
{
return
tideways_disable
();
}
private
function
getProfileFlagMap
()
{
return
array
(
ProfilingFlags
::
CPU
=>
TIDEWAYS_FLAGS_CPU
,
ProfilingFlags
::
MEMORY
=>
TIDEWAYS_FLAGS_MEMORY
,
ProfilingFlags
::
NO_BUILTINS
=>
TIDEWAYS_FLAGS_NO_BUILTINS
,
ProfilingFlags
::
NO_SPANS
=>
TIDEWAYS_FLAGS_NO_SPANS
,
);
}
}
vendor/perftools/php-profiler/src/Profilers/TidewaysXHProf.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Profilers
;
use
Xhgui\Profiler\ProfilingFlags
;
/**
* v5 (tideways_xhprof)
*
* @see https://github.com/tideways/php-profiler-extension
*/
class
TidewaysXHProf
extends
AbstractProfiler
{
const
EXTENSION_NAME
=
'tideways_xhprof'
;
public
function
isSupported
()
{
return
extension_loaded
(
self
::
EXTENSION_NAME
);
}
/**
* @see https://github.com/tideways/php-xhprof-extension#usage
*/
public
function
enable
(
$flags
=
array
(),
$options
=
array
())
{
tideways_xhprof_enable
(
$this
->
combineFlags
(
$flags
,
$this
->
getProfileFlagMap
()));
}
public
function
disable
()
{
return
tideways_xhprof_disable
();
}
private
function
getProfileFlagMap
()
{
return
array
(
ProfilingFlags
::
CPU
=>
TIDEWAYS_XHPROF_FLAGS_CPU
,
ProfilingFlags
::
MEMORY
=>
TIDEWAYS_XHPROF_FLAGS_MEMORY
,
ProfilingFlags
::
NO_BUILTINS
=>
TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS
,
ProfilingFlags
::
NO_SPANS
=>
0
,
);
}
}
vendor/perftools/php-profiler/src/Profilers/UProfiler.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Profilers
;
use
Xhgui\Profiler\ProfilingFlags
;
class
UProfiler
extends
AbstractProfiler
{
const
EXTENSION_NAME
=
'uprofiler'
;
public
function
isSupported
()
{
return
extension_loaded
(
self
::
EXTENSION_NAME
);
}
public
function
enable
(
$flags
=
array
(),
$options
=
array
())
{
uprofiler_enable
(
$this
->
combineFlags
(
$flags
,
$this
->
getProfileFlagMap
()),
$options
);
}
public
function
disable
()
{
return
uprofiler_disable
();
}
private
function
getProfileFlagMap
()
{
return
array
(
ProfilingFlags
::
CPU
=>
UPROFILER_FLAGS_CPU
,
ProfilingFlags
::
MEMORY
=>
UPROFILER_FLAGS_MEMORY
,
ProfilingFlags
::
NO_BUILTINS
=>
UPROFILER_FLAGS_NO_BUILTINS
,
ProfilingFlags
::
NO_SPANS
=>
0
,
);
}
}
vendor/perftools/php-profiler/src/Profilers/XHProf.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Profilers
;
use
Xhgui\Profiler\ProfilingFlags
;
class
XHProf
extends
AbstractProfiler
{
const
EXTENSION_NAME
=
'xhprof'
;
public
function
isSupported
()
{
return
extension_loaded
(
self
::
EXTENSION_NAME
);
}
/**
* @see https://www.php.net/manual/en/function.xhprof-enable.php
*/
public
function
enable
(
$flags
=
array
(),
$options
=
array
())
{
xhprof_enable
(
$this
->
combineFlags
(
$flags
,
$this
->
getProfileFlagMap
()),
$options
);
}
public
function
disable
()
{
return
xhprof_disable
();
}
/**
* @see https://www.php.net/manual/en/xhprof.constants.php
*/
private
function
getProfileFlagMap
()
{
/*
* This is disabled on PHP 5.5+ as it causes a segfault
*
* @see https://github.com/perftools/xhgui-collector/commit/d1236d6422bfc42ac212befd0968036986885ccd
*/
$noBuiltins
=
PHP_MAJOR_VERSION
===
5
&&
PHP_MINOR_VERSION
>
4
?
0
:
XHPROF_FLAGS_NO_BUILTINS
;
return
array
(
ProfilingFlags
::
CPU
=>
XHPROF_FLAGS_CPU
,
ProfilingFlags
::
MEMORY
=>
XHPROF_FLAGS_MEMORY
,
ProfilingFlags
::
NO_BUILTINS
=>
$noBuiltins
,
ProfilingFlags
::
NO_SPANS
=>
0
,
);
}
}
vendor/perftools/php-profiler/src/ProfilingData.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler
;
class
ProfilingData
{
/** @var array */
private
$excludeEnv
;
/** @var callable|null */
private
$simpleUrl
;
/** @var callable|null */
private
$replaceUrl
;
public
function
__construct
(
array
$config
=
array
())
{
$this
->
excludeEnv
=
isset
(
$config
[
'profiler.exclude-env'
])
?
(
array
)
$config
[
'profiler.exclude-env'
]
:
array
();
$this
->
simpleUrl
=
isset
(
$config
[
'profiler.simple_url'
])
?
$config
[
'profiler.simple_url'
]
:
null
;
$this
->
replaceUrl
=
isset
(
$config
[
'profiler.replace_url'
])
?
$config
[
'profiler.replace_url'
]
:
null
;
}
/**
* @return array
*/
public
function
getProfilingData
(
array
$profile
)
{
$url
=
$this
->
getUrl
();
$requestTimeFloat
=
explode
(
'.'
,
$_SERVER
[
'REQUEST_TIME_FLOAT'
]);
if
(
!
isset
(
$requestTimeFloat
[
1
]))
{
$requestTimeFloat
[
1
]
=
0
;
}
$allowedServerKeys
=
array
(
'DOCUMENT_ROOT'
,
'HTTPS'
,
'HTTP_HOST'
,
'HTTP_USER_AGENT'
,
'PATH_INFO'
,
'PHP_AUTH_USER'
,
'PHP_SELF'
,
'QUERY_STRING'
,
'REMOTE_ADDR'
,
'REMOTE_USER'
,
'REQUEST_METHOD'
,
'REQUEST_TIME'
,
'REQUEST_TIME_FLOAT'
,
'SERVER_ADDR'
,
'SERVER_NAME'
,
'UNIQUE_ID'
,
);
$serverMeta
=
array_intersect_key
(
$_SERVER
,
array_flip
(
$allowedServerKeys
));
$meta
=
array
(
'url'
=>
$url
,
'get'
=>
$_GET
,
'env'
=>
$this
->
getEnvironment
(
$_ENV
),
'SERVER'
=>
$serverMeta
,
'simple_url'
=>
$this
->
getSimpleUrl
(
$url
),
'request_ts_micro'
=>
array
(
'sec'
=>
$requestTimeFloat
[
0
],
'usec'
=>
$requestTimeFloat
[
1
]),
// these are superfluous and should be dropped in the future
'request_ts'
=>
array
(
'sec'
=>
$requestTimeFloat
[
0
],
'usec'
=>
0
),
'request_date'
=>
date
(
'Y-m-d'
,
$requestTimeFloat
[
0
]),
);
$data
=
array
(
'profile'
=>
$profile
,
'meta'
=>
$meta
,
);
return
$data
;
}
/**
* @param array $env
* @return array
*/
private
function
getEnvironment
(
array
$env
)
{
foreach
(
$this
->
excludeEnv
as
$key
)
{
unset
(
$env
[
$key
]);
}
return
$env
;
}
/**
* Creates a simplified URL given a standard URL.
* Does the following transformations:
*
* - Remove numeric values after =.
*
* @param string $url
* @return string
*/
private
function
getSimpleUrl
(
$url
)
{
if
(
is_callable
(
$this
->
simpleUrl
))
{
return
call_user_func
(
$this
->
simpleUrl
,
$url
);
}
return
preg_replace
(
'/=\d+/'
,
''
,
$url
);
}
/**
* @return string
*/
private
function
getUrl
()
{
$url
=
array_key_exists
(
'REQUEST_URI'
,
$_SERVER
)
?
$_SERVER
[
'REQUEST_URI'
]
:
null
;
if
(
!
$url
&&
isset
(
$_SERVER
[
'argv'
]))
{
$cmd
=
basename
(
$_SERVER
[
'argv'
][
0
]);
$url
=
$cmd
.
' '
.
implode
(
' '
,
array_slice
(
$_SERVER
[
'argv'
],
1
));
}
if
(
is_callable
(
$this
->
replaceUrl
))
{
$url
=
call_user_func
(
$this
->
replaceUrl
,
$url
);
}
return
$url
;
}
}
vendor/perftools/php-profiler/src/ProfilingFlags.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler
;
final
class
ProfilingFlags
{
const
CPU
=
'PROFILER_CPU_PROFILING'
;
const
MEMORY
=
'PROFILER_MEMORY_PROFILING'
;
const
NO_BUILTINS
=
'NO_BUILTINS'
;
const
NO_SPANS
=
'NO_SPANS'
;
}
vendor/perftools/php-profiler/src/Saver/AbstractSaver.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Saver
;
use
Xhgui_Saver_Interface
;
abstract
class
AbstractSaver
implements
SaverInterface
{
protected
$saver
;
public
function
__construct
(
Xhgui_Saver_Interface
$saver
)
{
$this
->
saver
=
$saver
;
}
public
function
save
(
array
$data
)
{
return
$this
->
saver
->
save
(
$data
);
}
}
vendor/perftools/php-profiler/src/Saver/FileSaver.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Saver
;
class
FileSaver
implements
SaverInterface
{
/** @var string */
private
$file
;
public
function
__construct
(
$file
)
{
$this
->
file
=
$file
;
}
public
function
isSupported
()
{
return
$this
->
file
&&
is_writable
(
dirname
(
$this
->
file
));
}
public
function
save
(
array
$data
)
{
$json
=
json_encode
(
$data
);
return
file_put_contents
(
$this
->
file
,
$json
.
PHP_EOL
,
FILE_APPEND
);
}
}
vendor/perftools/php-profiler/src/Saver/MongoSaver.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Saver
;
use
Xhgui_Saver_Mongo
;
/**
* @property Xhgui_Saver_Mongo $saver
*/
class
MongoSaver
extends
AbstractSaver
{
public
function
isSupported
()
{
if
(
!
$this
->
saver
instanceof
Xhgui_Saver_Mongo
)
{
return
false
;
}
return
class_exists
(
'MongoClient'
);
}
public
function
save
(
array
$data
)
{
if
(
isset
(
$data
[
'profile'
]))
{
$data
[
'profile'
]
=
$this
->
encodeProfile
(
$data
[
'profile'
]);
}
$result
=
parent
::
save
(
$data
);
return
!
empty
(
$result
);
}
/**
* MongoDB can't save keys with values containing a dot:
*
* InvalidArgumentException: invalid document for insert: keys cannot contain ".":
* "Zend_Controller_Dispatcher_Standard::loadClass==>load::controllers/ArticleController.php"
*
* Replace the dots with underscrore in keys.
*
* @link https://github.com/perftools/xhgui/issues/209
*/
private
function
encodeProfile
(
array
$profile
)
{
$results
=
array
();
foreach
(
$profile
as
$k
=>
$v
)
{
if
(
strpos
(
$k
,
'.'
)
!==
false
)
{
$k
=
str_replace
(
'.'
,
'_'
,
$k
);
}
$results
[
$k
]
=
$v
;
}
return
$results
;
}
}
vendor/perftools/php-profiler/src/Saver/PdoSaver.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Saver
;
use
Xhgui_Saver_Pdo
;
/**
* @property Xhgui_Saver_Pdo $saver
*/
class
PdoSaver
extends
AbstractSaver
{
public
function
isSupported
()
{
if
(
!
$this
->
saver
instanceof
Xhgui_Saver_Pdo
)
{
return
false
;
}
return
class_exists
(
'PDO'
);
}
public
function
save
(
array
$data
)
{
parent
::
save
(
$data
);
return
true
;
}
}
vendor/perftools/php-profiler/src/Saver/SaverInterface.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Saver
;
interface
SaverInterface
{
/**
* @return bool
*/
public
function
isSupported
();
/**
* @return bool
*/
public
function
save
(
array
$data
);
}
vendor/perftools/php-profiler/src/Saver/StackSaver.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Saver
;
use
Exception
;
/**
* Save to stack of savers.
*
* Supports saving to all savers, or to first successful one.
*/
class
StackSaver
implements
SaverInterface
{
/** @var array */
private
$savers
;
/** @var bool */
private
$saveAll
;
public
function
__construct
(
array
$savers
,
$saveAll
=
false
)
{
$this
->
savers
=
$this
->
validateSavers
(
$savers
);
$this
->
saveAll
=
(
bool
)
$saveAll
;
}
public
function
isSupported
()
{
return
count
(
$this
->
savers
)
>
0
;
}
public
function
save
(
array
$data
)
{
$result
=
false
;
foreach
(
$this
->
savers
as
$saver
)
{
try
{
if
(
!
$saver
->
save
(
$data
))
{
continue
;
}
$result
=
true
;
}
catch
(
Exception
$e
)
{
continue
;
}
// if not save all, then break on first successful save
if
(
!
$this
->
saveAll
)
{
break
;
}
}
return
$result
;
}
private
function
validateSavers
(
array
$savers
)
{
$result
=
array
();
foreach
(
$savers
as
$saver
)
{
try
{
if
(
!
$saver
->
isSupported
())
{
continue
;
}
}
catch
(
Exception
$e
)
{
continue
;
}
$result
[]
=
$saver
;
}
return
$result
;
}
}
vendor/perftools/php-profiler/src/Saver/UploadSaver.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler\Saver
;
use
Xhgui\Profiler\Exception\ProfilerException
;
class
UploadSaver
implements
SaverInterface
{
/** @var string */
private
$url
;
/** @var int */
private
$timeout
;
public
function
__construct
(
$url
,
$token
,
$timeout
)
{
$this
->
url
=
$url
;
if
(
$token
)
{
$this
->
url
.=
'?&token='
.
$token
;
}
$this
->
timeout
=
$timeout
;
}
public
function
isSupported
()
{
return
$this
->
url
&&
function_exists
(
'curl_init'
);
}
public
function
save
(
array
$data
)
{
$json
=
json_encode
(
$data
);
$this
->
submit
(
$this
->
url
,
$json
);
return
true
;
}
/**
* @param string $url
* @param string $payload
*/
private
function
submit
(
$url
,
$payload
)
{
$ch
=
curl_init
(
$url
);
if
(
!
$ch
)
{
throw
new
ProfilerException
(
'Failed to create cURL resource'
);
}
$headers
=
array
(
// Prefer to receive JSON back
'Accept: application/json'
,
// The sent data is JSON
'Content-Type: application/json'
,
);
$res
=
curl_setopt_array
(
$ch
,
array
(
CURLOPT_CUSTOMREQUEST
=>
'POST'
,
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_POSTFIELDS
=>
$payload
,
CURLOPT_FOLLOWLOCATION
=>
1
,
CURLOPT_HTTPHEADER
=>
$headers
,
CURLOPT_TIMEOUT
=>
$this
->
timeout
,
));
if
(
!
$res
)
{
throw
new
ProfilerException
(
'Failed to set cURL options'
);
}
$result
=
curl_exec
(
$ch
);
if
(
$result
===
false
)
{
throw
new
ProfilerException
(
'Failed to submit data'
);
}
curl_close
(
$ch
);
$response
=
json_decode
(
$result
,
true
);
if
(
!
$response
)
{
throw
new
ProfilerException
(
'Failed to decode response'
);
}
if
(
isset
(
$response
[
'error'
])
&&
$response
[
'error'
])
{
$message
=
isset
(
$response
[
'message'
])
?
$response
[
'message'
]
:
'Error in response'
;
throw
new
ProfilerException
(
$message
);
}
}
}
vendor/perftools/php-profiler/src/SaverFactory.php
0 → 100644
View file @
7b4d4a9f
<?php
namespace
Xhgui\Profiler
;
use
Xhgui\Profiler\Exception\ProfilerException
;
use
Xhgui\Profiler\Saver\SaverInterface
;
use
Xhgui_Saver
;
use
Xhgui_Saver_Interface
;
final
class
SaverFactory
{
/**
* @param string $saveHandler
* @param array $config
* @return SaverInterface|null
*/
public
static
function
create
(
$saveHandler
,
array
$config
=
array
())
{
switch
(
$saveHandler
)
{
case
Profiler
::
SAVER_FILE
:
$defaultConfig
=
array
(
'filename'
=>
null
,
);
$userConfig
=
isset
(
$config
[
'save.handler.file'
])
&&
is_array
(
$config
[
'save.handler.file'
])
?
$config
[
'save.handler.file'
]
:
array
();
$saverConfig
=
array_merge
(
$defaultConfig
,
$userConfig
);
$saver
=
new
Saver\FileSaver
(
$saverConfig
[
'filename'
]);
break
;
case
Profiler
::
SAVER_UPLOAD
:
$defaultConfig
=
array
(
'uri'
=>
null
,
// @deprecated
'url'
=>
null
,
'token'
=>
null
,
'timeout'
=>
3
,
);
$userConfig
=
isset
(
$config
[
'save.handler.upload'
])
&&
is_array
(
$config
[
'save.handler.upload'
])
?
$config
[
'save.handler.upload'
]
:
array
();
$saverConfig
=
array_merge
(
$defaultConfig
,
$userConfig
);
$saver
=
new
Saver\UploadSaver
(
$saverConfig
[
'url'
]
?:
$saverConfig
[
'uri'
],
$saverConfig
[
'token'
],
$saverConfig
[
'timeout'
]);
break
;
case
Profiler
::
SAVER_STACK
:
$defaultConfig
=
array
(
'savers'
=>
array
(),
'saveAll'
=>
false
,
);
$userConfig
=
isset
(
$config
[
'save.handler.stack'
])
&&
is_array
(
$config
[
'save.handler.stack'
])
?
$config
[
'save.handler.stack'
]
:
array
();
$saverConfig
=
array_merge
(
$defaultConfig
,
$userConfig
);
$savers
=
array
();
foreach
(
$saverConfig
[
'savers'
]
as
$saver
)
{
$instance
=
self
::
create
(
$saver
,
$config
);
if
(
$instance
)
{
$savers
[]
=
$instance
;
}
}
$saver
=
new
Saver\StackSaver
(
$savers
,
$saverConfig
[
'saveAll'
]);
break
;
default
:
// create via xhgui-collector
if
(
!
class_exists
(
'\Xhgui_Saver'
))
{
throw
new
ProfilerException
(
"For
{
$saveHandler
}
you need to install xhgui-collector package: composer require perftools/xhgui-collector"
);
}
$config
=
self
::
migrateConfig
(
$config
,
$saveHandler
);
$legacySaver
=
Xhgui_Saver
::
factory
(
$config
);
$saver
=
static
::
getAdapter
(
$legacySaver
);
break
;
}
if
(
!
$saver
||
!
$saver
->
isSupported
())
{
return
null
;
}
return
$saver
;
}
/**
* Prepare config for Xhgui_Saver specific to $saveHandler
*
* @param array $config
* @param string $saveHandler
* @return array
*/
private
static
function
migrateConfig
(
array
$config
,
$saveHandler
)
{
switch
(
$saveHandler
)
{
case
Profiler
::
SAVER_MONGODB
:
if
(
isset
(
$config
[
'save.handler.mongodb'
][
'dsn'
]))
{
$config
[
'db.host'
]
=
$config
[
'save.handler.mongodb'
][
'dsn'
];
}
if
(
isset
(
$config
[
'save.handler.mongodb'
][
'database'
]))
{
$config
[
'db.db'
]
=
$config
[
'save.handler.mongodb'
][
'database'
];
}
if
(
isset
(
$config
[
'save.handler.mongodb'
][
'options'
]))
{
$config
[
'db.options'
]
=
$config
[
'save.handler.mongodb'
][
'options'
];
}
else
{
$config
[
'db.options'
]
=
array
();
}
if
(
isset
(
$config
[
'save.handler.mongodb'
][
'driverOptions'
]))
{
$config
[
'db.driverOptions'
]
=
$config
[
'save.handler.mongodb'
][
'driverOptions'
];
}
else
{
$config
[
'db.driverOptions'
]
=
array
();
}
break
;
case
Profiler
::
SAVER_PDO
:
if
(
isset
(
$config
[
'save.handler.pdo'
]))
{
$config
[
'pdo'
]
=
$config
[
'save.handler.pdo'
];
}
break
;
}
$config
[
'save.handler'
]
=
$saveHandler
;
return
$config
;
}
private
static
function
getAdapter
(
Xhgui_Saver_Interface
$saver
)
{
$adapters
=
array
(
new
Saver\PdoSaver
(
$saver
),
new
Saver\MongoSaver
(
$saver
),
);
$available
=
array_filter
(
$adapters
,
function
(
SaverInterface
$adapter
)
{
return
$adapter
->
isSupported
();
});
return
current
(
$available
)
?:
null
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment