Commit 16a2eb05 authored by luhongguang's avatar luhongguang

update:op商品列表

parent aaa7a155
......@@ -59,8 +59,8 @@ class Distribution extends MysqlBase
return self::select($colums, $where);
}
public static function getCount($where)
public static function getCount($where, $columns = "*")
{
return self::count($where);
return self::count($columns, $where);
}
}
......@@ -60,8 +60,8 @@ class SubShop extends MysqlBase
return self::select($colums, $where);
}
public static function getCount($where)
public static function getCount($where, $columns = "*")
{
return self::count($where);
return self::count($columns, $where);
}
}
......@@ -59,8 +59,8 @@ class Distributor extends MysqlBase
return self::select($colums, $where);
}
public static function getCount($where)
public static function getCount($where, $columns = "*")
{
return self::count($where);
return self::count($columns, $where);
}
}
......@@ -51,8 +51,8 @@ class GoodsSku extends MysqlBase
return self::delete($where);
}
public static function getCount($where)
public static function getCount($where, $columns = "*")
{
return self::count($where);
return self::count($columns, $where);
}
}
\ No newline at end of file
......@@ -59,8 +59,8 @@ class Shop extends MysqlBase
return self::select($colums, $where);
}
public static function getCount($where)
public static function getCount($where, $columns = "*")
{
return self::count($where);
return self::count($columns, $where);
}
}
......@@ -60,8 +60,8 @@ class SubShop extends MysqlBase
return self::select($colums, $where);
}
public static function getCount($where)
public static function getCount($where, $columns = "*")
{
return self::count($where);
return self::count($columns, $where);
}
}
......@@ -502,19 +502,23 @@ class GoodsService
$where["name"] = $params["name"];
}
if (!empty($params["category_1_id"])) {
$where["category_1_id"] = $params["category_1_id"];
$category1Ids = explode(",", $params["category_1_id"]);
$where["category_1_id"] = $category1Ids;
}
if (!empty($params["category_2_id"])) {
$where["category_2_id"] = $params["category_2_id"];
$category2Ids = explode(",", $params["category_2_id"]);
$where["category_2_id"] = $category2Ids;
}
if (!empty($params["life_account_id"])) {
$where["life_account_id"] = $params["life_account_id"];
}
if (!empty($params["status"])) {
$where["status"] = $params["status"];
$status = explode(",", $params["status"]);
$where["status"] = $status;
}
if (!empty($params["online_status"])) {
$where["online_status"] = $params["online_status"];
$onlineStatus = explode(",", $params["online_status"]);
$where["online_status"] = $onlineStatus;
}
$count = GoodsSku::getCount($where);
......
......@@ -79,7 +79,7 @@ class SocialCreditCertification
'databaseImageContent' => $base64_image
];
$result = (new Request())->post(self::ocr_bussiness_url, $post_data, 3000, 'json',[],1);
$result = (new Request())->post(self::ocr_bussiness_url, $post_data, 2500, 'json',[],1);
if (isset($result['code'],$result['response']) && $result['code'] === 0 ) {
return $result['response'];
......
<?php
namespace Api\PhpServices\Interaction;
use Api\PhpUtils\Common\Docid;
use Api\PhpUtils\Redis\RedisUtil;
use Api\PhpUtils\Log\FileLog;
use Redis;
/**
* 使用redis存储文章的动态计数,目前包括'like','down','comment_count','up','comment_like','login_up','play_times'
* 以上字段在redis中存储时分别缩写为:'l','d','cc','u','cl','lu','pt'
* 为节约redis内存,使用hash结构进行存储,对于news_开头文章与其他文章区别对待
*
* 对于news_开头文章hash的key即为docid,具体存储格式如下:
* 'news_a5205f59257f4d4d749ef933b4304ad7'=>array('l'=>1,'d'=>2,'cc'=>3232)
*
* 对于非news_开头文章hash的key为docid去掉后三位(1位有效位+2位校验位),hash内部的key为(docid倒数第三位+('l','d','cc','u','cl','lu','pt','t')等):
* 例如对于docid 06No4hkp,具体存储格式如下:
* '06No4'=>array('hl'=>1,'hd'=>2,'hcc'=>3232)
* 因为docid为62进制的数,因此每个hash结构下最多62*8=496个key
*/
class InterDynamic
{
private $key_map = array('follow' => 'fo', 'fans' => 'fa', 'digg' => 'di');
private $redis = null;
private $fields = [];
private $reverse_map = [];
//主库开启了rdb及aof,主库只写,从库只读
public function __construct($useMaster = false)
{
$this->fields = array_keys($this->key_map);
$this->reverse_map = array_flip($this->key_map);
// //文章动态计数哨兵集群 Sentinel apiConnect
$this->redis = RedisUtil::getInstance('count', ['serializer' => 'none', 'master' => $useMaster]);
}
public function get($docid, array $fields = array())
{
$ret = array();
try {
$fields = empty($fields) ? $this->fields : array_intersect($fields, $this->fields);
if (empty($fields)) {
return $ret;
}
$fields = $this->fieldsMap($fields);
if (strlen($docid) < 8) {
FileLog::waring('get dynamic doc redis failed', 'bad docid : ' . $docid);
}
if (substr($docid, 0, 5) === 'inte_') {
$redis_ret = $this->redis->hmget($docid, $fields);
// var_dump($this->reverse_map);
// var_dump($redis_ret);exit;
} else {
$temp = array();
$real_docid = substr(trim($docid), 0, -2);
$hkey = substr($real_docid, 0, -1);
foreach ($fields as $field) {
$temp[] = substr($real_docid, -1) . $field;
}
$redis_ret = $this->redis->hmget($hkey, $temp);
}
foreach ($redis_ret as $redis_ret_key => $redis_ret_value) {
if ($redis_ret_value !== false && $redis_ret_value >= 0) {
if (substr($docid, 0, 5) === 'inte_') {
$ret[$this->reverse_map[$redis_ret_key]] = $redis_ret_value;
} else {
$ret[$this->reverse_map[substr($redis_ret_key, 1)]] = $redis_ret_value;
}
}
}
return $ret;
} catch (\Exception $e) {
FileLog::waring('get dynamic doc redis failed', $docid . ' ' . $e->getCode() . ' ' . $e->getMessage());
return $ret;
}
}
/**
* 可用倒数第三位不同的docid拼接同一条pipe减少请求次数,但实际情况中docid较为分散,每一条对应一个pipe比较清晰
* @param array $docids
* @param array $fields(可选值'like','down','comment_count','up','comment_like','login_up','play_times','top')
* @return array eg:
* array('06No4hkp'=>array('like'=>1,'up=>2'),'06No4hkm'=>array('like'=>1,'up=>2'))
*/
public function gets(array $docids, array $fields = array())
{
$ret = array();
try {
$fields = empty($fields) ? $this->fields : array_intersect($fields, $this->fields);
if (empty($fields) || empty($docids)) {
return $ret;
}
$fields = $this->fieldsMap($fields);
$gets = array();
//根据docid的两种情况拼接hash的hkey和mkey
foreach ($docids as $docid) {
if (strlen($docid) < 8) {
continue;
}
if (substr($docid, 0, 5) === 'inte_') {
$gets[] = array('docid' => $docid, 'hkey' => $docid, 'mkey' => $fields);
} else {
$temp = array();
$real_docid = substr(trim($docid), 0, -2);
$hkey = substr($real_docid, 0, -1);
foreach ($fields as $field) {
$temp[] = substr($real_docid, -1) . $field;
}
$gets[] = array('docid' => $docid, 'hkey' => $hkey, 'mkey' => $temp);
}
}
if (empty($gets)) {
return $ret;
}
//redis pipeline获取数据
$this->redis->multi(Redis::PIPELINE);
foreach ($gets as $get) {
$this->redis->hmget($get['hkey'], $get['mkey']);
}
$redis_rets = $this->redis->exec();
return $redis_rets == false ? $ret : $this->formatRedisRet($redis_rets, $gets, 'hmget');
} catch (\Exception $e) {
FileLog::waring('gets dynamic doc redis failed', implode(',', $docids) . ' ' . $e->getCode() . ' ' . $e->getMessage());
return $ret;
}
}
/**
* 批量写入数据
* @param [array] $data,格式如下:
* array(
* '06No4hkp'=>array('like'=>1,'down'=>2),
* '06No4hk1'=>array('comment_count'=>3,'up'=>4,'comment_like'=>'7'),
* )
* @return
*/
private function sets(array $data)
{
try {
if (empty($data)) {
return false;
}
foreach ($data as $docid => &$value) {
if (!Docid::validDocid($docid)) {
//throw new \Exception("bad docid " . $docid, -1);
}
}
$inserts = $this->getUpdateData($data, 'hmset');
if (empty($inserts)) {
return false;
}
$this->redis->multi(Redis::PIPELINE);
foreach ($inserts as $insert) {
if (isset($insert['hkey']) && isset($insert['value'])) {
$this->redis->hmset($insert['hkey'], $insert['value']);
}
}
$redis_ret = $this->redis->exec();
if (!empty($redis_ret)) {
return true;
}
return false;
} catch (\Exception $e) {
FileLog::waring('set dynamic doc redis failed', json_encode($data) . ' ' . $e->getCode() . ' ' . $e->getMessage());
return false;
}
}
/**
* 批量inc deinc
* @param [array] $data,格式如下:
* array(
* '06No4hkp'=>array('like'=>1,'down'=>2),
* '06No4hk1'=>array('comment_count'=>-3,'up'=>-4,'comment_like'=>'-7'),
* )
* @return 返回更新后的值
* array(
* '06No4hkp'=>array('like'=>12,'down'=>2),
* '06No4hk1'=>array('comment_count'=>3,'up'=>4,'comment_like'=>'7'),
* )
*/
private function hincrs(array $data)
{
$ret = array();
try {
if (empty($data)) {
return $ret;
}
foreach ($data as $docid => &$value) {
if (!Docid::validDocid($docid)) {
// throw new \Exception("bad docid " . $docid, -1);
}
}
$updates = $this->getUpdateData($data, 'hincby');
if (empty($updates)) {
return $ret;
}
$this->redis->multi(Redis::PIPELINE);
foreach ($updates as $update) {
$this->redis->hincrby($update['hkey'], $update['mkey'], $update['value']);
}
$redis_rets = $this->redis->exec();
return $redis_rets == false ? $ret : $this->formatRedisRet($redis_rets, $updates, 'hincby');
} catch (\Exception $e) {
FileLog::waring('update dynamic doc redis failed', json_encode($data) . ' ' . $e->getCode() . ' ' . $e->getMessage());
return $ret;
}
}
/**
* 映射'like','down','comment_count','up','comment_like'到缩写
* @param array $fields
* @return [type]
*/
private function fieldsMap(array $fields)
{
$ret = array();
foreach ($fields as $field) {
if (isset($this->key_map[$field])) {
$ret[] = $this->key_map[$field];
}
}
return $ret;
}
private function fieldsKeyMap(array $doc)
{
$ret = array();
$key_map = $this->key_map;
foreach ($key_map as $key => $value) {
if (isset($doc[$key])) {
$ret[$value] = $doc[$key];
}
}
return $ret;
}
/**
* 获取特定格式化数据,用于redis pipeline
* @param array $records
* @param string $type hmset or hincby
* @return array
* eg:hmset
* array(
* array('hkey'=>'06No4','value'=>array('6d'=>123,'6cl'=>'123')),
* array('hkey'=>'06No6','value'=>array('4d'=>123,'4cl'=>'123')),
* )
* eg:hincby
* array(
* array('docid'=>'06No42qP','hkey'=>'06No4','mkey'=>'2cl','value'=>123),
* array('docid'=>'news_a5205f59257f4d4d749ef933b4304ad7','hkey'=>'news_a5205f59257f4d4d749ef933b4304ad7','mkey'=>'cl','value'=>123),
* )
*/
private function getUpdateData(array $records, $type)
{
$ret = array();
foreach ($records as $docid => $record) {
if (substr($docid, 0, 5) === 'inte_') {
if ($type == 'hmset') {
$ret[] = array('hkey' => $docid, 'value' => $this->fieldsKeyMap($record));
} elseif ($type == 'hincby') {
$value = $this->fieldsKeyMap($record);
foreach ($value as $key1 => $value1) {
$ret[] = array('docid' => $docid, 'hkey' => $docid, 'mkey' => $key1, 'value' => $value1);
}
}
} else {
$values = $this->fieldsKeyMap($record);
$real_docid = substr(trim($docid), 0, -2);
$hkey = substr($real_docid, 0, -1);
$mkey = substr($real_docid, -1);
$temp = array();
foreach ($values as $key => $value) {
$temp[$mkey . $key] = $value;
}
if ($type == 'hmset') {
$ret[] = array('hkey' => $hkey, 'value' => $temp);
} elseif ($type == 'hincby') {
foreach ($temp as $key2 => $value2) {
$ret[] = array('docid' => $docid, 'hkey' => $hkey, 'mkey' => $key2, 'value' => $value2);
}
}
}
}
return $ret;
}
/**
* //格式化redis返回值
* @param array $redis_rets redis pipeline返回值
* @param array $pipe_datas pipe迭代前原始值
* @param string $type hmset or hincby
* @return array
*/
private function formatRedisRet(array $redis_rets, array $pipe_datas, $type)
{
$ret_length = is_array($redis_rets) ? count($redis_rets) : 0;
$ret = array();
for ($i = 0; $i < $ret_length; $i++) {
if ($type == 'hmget') {
foreach ($redis_rets[$i] as $redis_key => $redis_value) {
if ($redis_value !== false && is_numeric($redis_value)) {
if (substr($pipe_datas[$i]['docid'], 0, 5) === 'inte_') {
$ret_key = $this->reverse_map[$redis_key];
$ret[$pipe_datas[$i]['docid']][$ret_key] = intval($redis_value);
} else {
$ret_key = $this->reverse_map[substr($redis_key, 1)];
$ret[$pipe_datas[$i]['docid']][$ret_key] = intval($redis_value);
}
}
}
} elseif ($type == 'hincby') {
if ($redis_rets[$i] !== false && is_numeric($redis_rets[$i])) {
if (substr($pipe_datas[$i]['docid'], 0, 5) === 'inte_') {
$ret_key = $this->reverse_map[$pipe_datas[$i]['mkey']];
} else {
$ret_key = $this->reverse_map[substr($pipe_datas[$i]['mkey'], 1)];
}
$int_value = intval($redis_rets[$i]);
$ret[$pipe_datas[$i]['docid']][$ret_key] = $int_value >= 0 ? $int_value : 0;
}
}
}
return $ret;
}
private function incrCount($docid, $field, $value)
{
$result = $this->hincrs(array($docid => array($field => $value)));
if (isset($result[$docid][$field])) {
if ($result[$docid][$field] > 0) {
return $result[$docid][$field];
} else {
$this->sets(array($docid => array($field => 0)));
return 0;
}
} else {
return 0;
}
}
private function setCount($docid, $field, $value)
{
return $this->sets(array($docid => array($field => $value)));
}
public function incrCommentCount($docid, $value = 1)
{
$this->incrCount($docid, 'comment_count', $value);
}
public function incrLike($docid, $value = 1)
{
$this->incrCount($docid, 'like', $value);
}
public function incrLoginThumbsup($docid, $value = 1)
{
$this->incrCount($docid, 'login_up', $value);
}
public function incrThumbsup($docid, $value = 1)
{
$this->incrCount($docid, 'up', $value);
}
public function incrThumbsdown($docid, $value = 1)
{
$this->incrCount($docid, 'down', $value);
}
public function incrCommentLike($docid, $value = 1)
{
$this->incrCount($docid, 'comment_like', $value);
}
public function incrTop($docid, $value = 1)
{
$this->incrCount($docid, 'top', $value);
}
public function setCommentCount($docid, $value)
{
$this->setCount($docid, 'comment_count', $value);
}
public function setThumbsdown($docid, $value)
{
$this->setCount($docid, 'down', $value);
}
public function incrPlayTimes($docid, $value = 1)
{
$this->incrCount($docid, 'play_times', $value);
}
public function setPlayTimes($docid, $value)
{
return $this->setCount($docid, 'play_times', $value);
}
public function setFollow($docid, $value)
{
return $this->setCount($docid, 'follow', $value);
}
public function incrFollow($docid, $value = 1)
{
$this->incrCount($docid, 'follow', $value);
}
public function setFans($docid, $value)
{
return $this->setCount($docid, 'fans', $value);
}
public function incrFans($docid, $value = 1)
{
$this->incrCount($docid, 'follow', $value);
}
public function setDigg($docid, $value)
{
return $this->setCount($docid, 'digg', $value);
}
public function incrDigg($docid, $value = 1)
{
$this->incrCount($docid, 'digg', $value);
}
}
<?php
/**
* Description of JwUser.php
*
......@@ -23,8 +24,8 @@ class JwUser
*/
public function getUserInfo($params)
{
$url = config('interface','service.jw_user.get_user_info');
if(!$url){
$url = config('interface', 'service.jw_user.get_user_info');
if (!$url) {
throw new CodeSpecialException("failed");
}
......@@ -34,10 +35,10 @@ class JwUser
$params = ["mobilePhone" => $params['mobile']];
$user_info = (new TimeOut())->runGet($url, $params);
if(!$user_info){
if (!$user_info) {
throw new CodeSpecialException("timeout");
}
return $user_info;
return $user_info;
}
/**
* 获取单条信息
......@@ -45,8 +46,8 @@ class JwUser
*/
public function getUserByUserId($params)
{
$url = config('interface','service.jw_user.get_user_info_by_user_id');
if(!$url){
$url = config('interface', 'service.jw_user.get_user_info_by_user_id');
if (!$url) {
throw new CodeSpecialException("failed");
}
......@@ -56,16 +57,16 @@ class JwUser
$params = ["userId" => $params['user_id']];
$user_info = (new TimeOut())->runPost($url, $params);
if(!$user_info){
if (!$user_info) {
throw new CodeSpecialException("timeout");
}
return $user_info;
return $user_info;
}
public function getUserList($params)
{
$url = config('interface','service.jw_user.get_user_list');
if(!$url){
$url = config('interface', 'service.jw_user.get_user_list');
if (!$url) {
throw new CodeSpecialException("failed");
}
......@@ -75,10 +76,10 @@ class JwUser
$params = ["userIds" => $params['user_id']];
$user_info = (new TimeOut())->runPost($url, $params);
if(!$user_info){
if (!$user_info) {
throw new CodeSpecialException("timeout");
}
return $user_info;
return $user_info;
}
......@@ -89,39 +90,61 @@ class JwUser
*/
public function getAllCityTree()
{
$url = config('interface','service.jw_user.get_all_city_tree');
if(!$url){
$url = config('interface', 'service.jw_user.get_all_city_tree');
if (!$url) {
throw new CodeSpecialException("failed");
}
$params = [];
$city_list = (new TimeOut())->runGet($url, $params);
if(!$city_list){
if (!$city_list) {
throw new CodeSpecialException("timeout");
}
return $city_list;
}
/**
* 保存用户与token的对应关系接口
* 支持的token prefix:MMPP 小米推送,UMPP 友盟推送,GTPP 个推
*
*/
/**
* 保存用户与token的对应关系接口
* 支持的token prefix:MMPP 小米推送,UMPP 友盟推送,GTPP 个推
*
*/
public function savePushToken($params)
{
$url = config('interface','service.jw_user.save_push_token');
if(!$url){
$url = config('interface', 'service.jw_user.save_push_token');
if (!$url) {
throw new CodeSpecialException("failed");
}
if (empty($params)) {
throw new CodeSpecialException("failed");
}
$pushToken = (new TimeOut())->runPost($url, $params);
if(!$pushToken){
if (!$pushToken) {
throw new CodeSpecialException("timeout");
}
return $pushToken;
}
/**
* 获取简网用户动态
*/
public function getUserListWithDynamic($params)
{
$url = config('interface', 'service.jw_user.get_user_dynamic');
if (!$url) {
throw new CodeSpecialException("failed");
}
if (empty($params['user_id'])) {
throw new CodeSpecialException("failed");
}
$params = ["userIds" => $params['user_id']];
$list = (new TimeOut())->runPost($url, $params);
if (!$list) {
throw new CodeSpecialException("timeout");
}
return $list;
}
}
......@@ -37,4 +37,42 @@ class Account
}
return $list;
}
/**
* 批量获取生活号表数据
*
*@param $params['user_id'] 主键id
*
*/
public static function getLifeList($params)
{
$url = config('interface', 'merchant.account.get_life_list');
if (!$url) {
throw new CodeSpecialException("failed");
}
$list = (new TimeOut())->runGet($url, $params);
if (!$list) {
throw new CodeSpecialException("timeout");
}
return $list;
}
/**
* 批量获取用户表数据
*
*@param $params['user_id'] 主键id
*
*/
public static function getUserList($params)
{
$url = config('interface', 'merchant.account.get_user_list');
if (!$url) {
throw new CodeSpecialException("failed");
}
$list = (new TimeOut())->runGet($url, $params);
if (!$list) {
throw new CodeSpecialException("timeout");
}
return $list;
}
}
......@@ -148,7 +148,7 @@ class Request
$options['on_stats'] = function (TransferStats $stats) use ($use_mon, $url) {
$this->result['http_code'] = $stats->getHandlerStat('http_code');
if (!empty($use_mon)) {
//MonUtil::proxyMon($url, $stats->getHandlerStat('http_code'), round($stats->getHandlerStat('total_time'),4) * 1000);
MonUtil::proxyMon($use_mon,$url, $stats->getHandlerStat('http_code'), round($stats->getHandlerStat('total_time'),4) * 1000);
}
};
//异步post请求
......@@ -185,8 +185,8 @@ class Request
$ch = self::CURL($url, $timeout, $headers, $post, false, $has_curl_file=false, "PUT");
if (is_resource($ch) === true)
{
}
$response = curl_exec($ch);
if ($error = curl_error($ch))
......@@ -265,8 +265,76 @@ class Request
}
return $ch;
}
static function NEW_CURL($url, $timeout, $retries, $headers, $post = false, $proxy = false, $has_curl_file = null, $method = 'GET', $curl_opts = array())
{
$use_mon = false; //是否使用监控打点服务标志
//$proxy 取值为true,表示依赖第三方服务,要进行监控打点
if($proxy == true){
$use_mon = true;
$proxy = false;
}
$ch = self::CURL($url, $timeout, $headers, $post, $proxy, $has_curl_file, $method, $curl_opts);
$result = false;
if (is_resource($ch) === true)
{
while (($result === false) && ($retries-- > 0))
{
$result = curl_exec($ch);
}
if (curl_errno($ch) !== 0)
{
$GLOBALS['ERROR_MESSAGE'] = curl_error($ch);
}
$GLOBALS['HTTP_CODE'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if( isset($GLOBALS['ENABLE_HEADER_REQUEST_TIME']) )
{
$GLOBALS['BELENDER_CURL_INFO'] = curl_getinfo($ch);
//在返回header中添加blender响应时间
$GLOBALS['DEPENDENT-REQUEST-TIME'] = round(curl_getinfo($ch, CURLINFO_TOTAL_TIME),4).'|'.round(curl_getinfo($ch, CURLINFO_NAMELOOKUP_TIME),4).'|'.round(curl_getinfo($ch, CURLINFO_CONNECT_TIME),4);
$GLOBALS['DEPENDENT-REQUEST'] = array('url'=>$url, 'method'=>$method, 'body'=>$post);
$GLOBALS['DEPENDENT-URI'] = parse_url($url, PHP_URL_PATH);
if ($GLOBALS['HTTP_CODE'] === 0)
{
$GLOBALS['DEPENDENT-STATUS'] = 'timeout';
}
else if ($GLOBALS['HTTP_CODE'] !== 200)
{
$GLOBALS['DEPENDENT-STATUS'] = '5xx';
}else
{
$GLOBALS['DEPENDENT-STATUS'] = 'normal';
}
}
// //监控打点,模块名默认为第三方服务url,指标为请求返回的HTTP_code与总响应时间
// //HTTP_CODE如果未设置,默认为-999
// if($use_mon){
// MonUtil::proxy_mon($url,
// isset($GLOBALS['HTTP_CODE']) ? $GLOBALS['HTTP_CODE'] : -999,
// false,
// round(curl_getinfo($ch, CURLINFO_TOTAL_TIME),4) * 1000
// );
// }
unset($GLOBALS['ENABLE_HEADER_REQUEST_TIME']);
// if ($post === false)
// {
// write_log($url, curl_errno($ch), curl_error($ch), __LINE__, __FILE__, '', $result);
// }
// else
// {
// write_log($url, curl_errno($ch), curl_error($ch), __LINE__, __FILE__, 'POST body '.var_export($post, true), $result);
// }
curl_close($ch);
}
return $result;
}
public function put($url, $params = [], $timeout = 0,$content_type = '', $headers = [], $retry = 0, $use_mon = true, $proxy = '')
{
try {
......@@ -287,7 +355,7 @@ class Request
$client = (new Base())->initClient($config, $url, $params);
//构造配置
if (!empty($params)) {
if ($content_type == 'json') {
......@@ -405,6 +473,11 @@ class Request
}
}
public function CURL_POST($url, $post, $timeout = 10000, $retries = 1, $headers = false, $proxy = false, $curl_opts = array())
{
return self::NEW_CURL($url, $timeout,$retries, $headers, $post, $proxy, null, 'POST', $curl_opts);
}
/**
* 并发执行get请求
* @param array $urls [0=>xxx,1=>xxx]
......
......@@ -89,7 +89,7 @@ class MonUtil{
*/
public static function getMsg($module, $index, $value, $type){
if(is_string($module) && !empty($module) && is_string($index) && !empty($index)){
return "Ydbot.statsd.superfe.api." . $module . "." . $index . ".1sec:" . $value . "|" . $type;
return "Ydbot.statsd.superfe.bp." . $module . "." . $index . ".1sec:" . $value . "|" . $type;
}
return "";
......@@ -190,4 +190,25 @@ class MonUtil{
return $result;
}
/**
* 统计下接口返回的code
*
* @param $code
* @return mixed 监控打点数据或""
*/
public static function uri_code_count($code){
$uri = explode('?', $_SERVER['REQUEST_URI']);
//获取服务器的名字作为模块名,因grafana打点路径以"."分割,将服务器名中的"."转化为"_"
$module = str_replace(".", "_", $_SERVER['SERVER_NAME']);
//因grafana打点路径的key只支持大小写字母、数字、中划线和下划线,将uri中的"/"转化为"_"进行打点
$index = str_replace("/","_", strval($uri[0]));
//排除uri加后缀.php的情况
$index = explode(".", $index);
$index = substr($index[0],1). "." . strval($code);
return self::counting($module, $index, 1);
}
}
......@@ -21,16 +21,22 @@ use Api\PhpUtils\Log\FileLog;
* return number 插入为lasterInsertId:String 按需自己intval(),更新和删除返回影响条数
*
* 5. 根据镜像中php的版本选择使用version1.7.10 版本的Medoo类, 并进行了改造,去掉了join操作,增加了$options参数;
* $options参数可选项:
* - $options['max_execution_time'] = 10; // 单位毫秒
* - $options['rowCount'] = true; // 返回insert后的影响行数
* @see https://medoo.in (英文网站)
* @see https://medoo.lvtao.net (中文网站)
*/
/**
* @method static MysqlBase insert($data, $options)
* @method static MysqlBase insertDuplicate($data, $duplicate)
* @method static MysqlBase update($data, $where)
* @method static MysqlBase delete($where)
* @method static MysqlBase select($columns, $where, $options)
* @method static MysqlBase selectMaster($columns, $where, $options)
* @method static MysqlBase selectForUpdate($columns, $where, $options)
* @method static MysqlBase getMaster($columns, $where, $options)
* @method static MysqlBase get($columns, $where, $options)
* @method static MysqlBase count($columns, $where)
......@@ -98,6 +104,8 @@ abstract class MysqlBase
"delete",
"selectMaster", // 或使用/*master*/强制路由,对主从实时性要求较高的场景使用,分布式系统尽量用消息代替查主库等其他方案
"getMaster",
"selectForUpdate",
"insertDuplicate",
];
/**
......@@ -154,51 +162,6 @@ abstract class MysqlBase
return self::formatResult($method, $arguments);
}
/**
* selectForUpdate
*
* @return array
*/
public static function selectForUpdate($columns, $where, $options = null)
{
$type = static::WRITE;
self::$dbCurrentConnect = self::$dbConnect[$type] = self::getConnection($type);
self::$sqlResut = self::$dbConnect[$type]->selectForUpdate(static::TABLE_NAME, $columns, $where, $options);
if (!self::catchError('selectForUpdate', [static::TABLE_NAME, $columns, $where, $options])) {
// 如果失败重试一次
self::$dbCurrentConnect = self::$dbConnect[$type] = self::getConnection($type);
self::$sqlResut = self::$dbConnect[$type]->selectForUpdate(static::TABLE_NAME, $columns, $where, $options);
if (!self::catchError('selectForUpdate', [static::TABLE_NAME, $columns, $where, $options])) {
return false;
}
}
return self::$sqlResut;
}
/**
* insertDuplicate
*
* 批量使用:Medoo::raw
* insertDuplicate([['id' => 4,'name' => 'test1'], ['id' => 5,'name' => 'test2']], ['name' => Medoo::raw('VALUES(name)')]);
*
* @return int 单条时返回1insert成功,返回2表示重复数据更新成功
*/
public static function insertDuplicate($data, $duplicate)
{
$type = static::WRITE;
self::$dbCurrentConnect = self::$dbConnect[$type] = self::getConnection($type);
self::$sqlResut = self::$dbConnect[$type]->insertDuplicate(static::TABLE_NAME, $data, $duplicate);
if (!self::catchError('insertDuplicate', [static::TABLE_NAME, $data, $duplicate])) {
// 如果失败重试一次
self::$dbCurrentConnect = self::$dbConnect[$type] = self::getConnection($type);
self::$sqlResut = self::$dbConnect[$type]->insertDuplicate(static::TABLE_NAME, $data, $duplicate);
if (!self::catchError('insertDuplicate', [static::TABLE_NAME, $data, $duplicate])) {
return false;
}
}
return self::formatResult('insertDuplicate', [static::TABLE_NAME, $data, $duplicate]);
}
/**
* 获取数据库连接
*
......
......@@ -2,7 +2,7 @@
namespace Api\PhpUtils\Mysql;
use Medoo\Medoo;
use Api\PhpUtils\Mysql\Medoo;
use Api\PhpUtils\Log\FileLog;
/**
......@@ -20,7 +20,7 @@ use Api\PhpUtils\Log\FileLog;
* return [] 查询结果为空
* return number 插入为lasterInsertId:String 按需自己intval(),更新和删除返回影响条数
*
* 5. 根据镜像中php的版本选择使用version1.7.10 版本的Medoo类,不要升级!
* 5. 根据镜像中php的版本选择使用version1.7.10 版本的Medoo类,并进行了改造,去掉了join操作,增加了$options参数;
* @see https://medoo.in (英文网站)
* @see https://medoo.lvtao.net (中文网站)
*/
......@@ -129,6 +129,8 @@ abstract class MysqlClusterBase
"delete",
"selectMaster", // 或使用/*master*/强制路由,对主从实时性要求较高的场景使用,分布式系统尽量用消息代替查主库等其他方案
"getMaster",
"selectForUpdate",
"insertDuplicate",
];
/**
......@@ -185,7 +187,7 @@ abstract class MysqlClusterBase
if (!self::catchError($method, $arguments)) {
// 如果失败重试一次
self::$dbCurrentConnect = self::$dbConnect[$type.':'.$dbShardingIndex] = self::getConnection($type, $dbShardingIndex, true);
self::$dbCurrentConnect = self::$dbConnect[$type.':'.$dbShardingIndex] = self::getConnection($type, $dbShardingIndex);
self::$sqlResut = call_user_func_array([self::$dbConnect[$type.':'.$dbShardingIndex], $method], $arguments);
if (!self::catchError($method, $arguments)) {
return false;
......@@ -429,12 +431,6 @@ abstract class MysqlClusterBase
case 'selectmaster':
case 'get':
case 'getmaster':
// 不允许用join操作
if (count($arguments) > 2) {
self::$errorInfo = ['validation', 0, "sql exception use join:" . $method . "-" . json_encode($arguments)];
FileLog::error("sql exception use join:" . $method . "-" . json_encode($arguments));
return false;
}
// 读取没有limit的强制加limit
if (!isset($arguments[1]['LIMIT'])) {
$arguments[1]['LIMIT'] = 5000;
......@@ -442,15 +438,6 @@ abstract class MysqlClusterBase
}
break;
case 'count':
// 不允许用join操作
if (count($arguments) > 1) {
self::$errorInfo = ['validation', 0, "sql exception use join:" . $method . "-" . json_encode($arguments)];
FileLog::error("sql exception use join:" . $method . "-" . json_encode($arguments));
return false;
}
break;
default:
break;
}
......@@ -591,10 +578,16 @@ abstract class MysqlClusterBase
// PDOStatement::rowCount() 返回上一个由对应的 PDOStatement 对象执行DELETE、 INSERT、或 UPDATE 语句受影响的行数。
return self::$sqlResut->rowCount();
}
// 单条插入返回最后插入行的ID
// 对于无AUTO_INCREMENT的表,可以指定返回影响的行数的参数
if (isset($arguments[2]['rowCount']) && $arguments[2]['rowCount']) {
// PDOStatement::rowCount() 返回上一个由对应的 PDOStatement 对象执行DELETE、 INSERT、或 UPDATE 语句受影响的行数。
return self::$sqlResut->rowCount();
}
// 单条默认插入返回最后插入行的lastInsertId,如果无AUTO_INCREMENT字段,返回NULL
return call_user_func_array([self::$dbCurrentConnect, 'id'], []);
break;
case 'update':
case 'delete':
// 返回上一个由对应的 PDOStatement 对象执行DELETE、 INSERT、或 UPDATE 语句受影响的行数。
......
......@@ -4,6 +4,26 @@
### MysqlBase 主从模式示例
``` php
$options参数可选项
- $options['max_execution_time'] = 10; // 单位毫秒
- $options['rowCount'] = true; // 返回insert后的影响行数
/**
* insertDuplicate
*
* 批量使用:Medoo::raw
* insertDuplicate([['id' => 4,'name' => 'test1'], ['id' => 5,'name' => 'test2']], ['name' => Medoo::raw('VALUES(name)')]);
*
* @return int 单条时返回1insert成功,返回2表示重复数据更新成功
*/
public static function insertDuplicate($data, $duplicate)
{}
<?php
namespace App\Models\demo\mysql;
......
......@@ -160,9 +160,7 @@ class WebLog
$log['request'] = $send_request;
}
$log['response']['status'] = $result['status']??'';
$log['response']['code'] = $result['code']??'';
$log['response']['reason'] = $result['reason']??'';
$log['response'] = $result;
if( !empty($GLOBALS['related_url']) )
{
......@@ -175,7 +173,7 @@ class WebLog
if (!empty($data))
{
$bp_website_pb_log_url = self::BP_WEBSITE_PB_LOG_URL;
$res = (new Request())->post($bp_website_pb_log_url, $data, 50, ['Content-Type: binary/octet-stream'], [], 1);
$res = (new Request())->CURL_POST($bp_website_pb_log_url, $data, 50, 1,array('Content-Type: binary/octet-stream'));
}
}
......
......@@ -32,7 +32,7 @@ private static $installed = array (
'aliases' =>
array (
),
'reference' => '84928268a3b67ce3c8f83c4e655aa5d05654c37b',
'reference' => 'aaa7a15562bb4388a4d9b639c7623edd5f44e2d7',
'name' => 'yidian/yaf_demo',
),
'versions' =>
......@@ -45,7 +45,7 @@ private static $installed = array (
array (
0 => '9999999-dev',
),
'reference' => '95cfa288e4777d976f53787882e5c4ae9e7592e6',
'reference' => 'efdbb7f13f8184d60b56b0fb876b8868147162ac',
),
'api/php_utils' =>
array (
......@@ -55,7 +55,7 @@ private static $installed = array (
array (
0 => '9999999-dev',
),
'reference' => '65546514336724128e7047b4a7704608f0400e80',
'reference' => '474c015979f967bcd045224c7e4f47c206dcfad7',
),
'elasticsearch/elasticsearch' =>
array (
......@@ -184,7 +184,7 @@ private static $installed = array (
'aliases' =>
array (
),
'reference' => '84928268a3b67ce3c8f83c4e655aa5d05654c37b',
'reference' => 'aaa7a15562bb4388a4d9b639c7623edd5f44e2d7',
),
),
);
......
......@@ -16,6 +16,7 @@ return array(
'Api\\PhpServices\\Daemon\\DaemonServiceInterface' => $vendorDir . '/api/php_services/src/Daemon/DaemonServiceInterface.php',
'Api\\PhpServices\\Doc\\DocDynamic' => $vendorDir . '/api/php_services/src/Doc/DocDynamic.php',
'Api\\PhpServices\\Idgen\\Idgen' => $vendorDir . '/api/php_services/src/Idgen/Idgen.php',
'Api\\PhpServices\\Interaction\\InterDynamic' => $vendorDir . '/api/php_services/src/Interaction/InterDynamic.php',
'Api\\PhpServices\\JwUser\\JwUser' => $vendorDir . '/api/php_services/src/JwUser/JwUser.php',
'Api\\PhpServices\\Ksy\\Ksyun' => $vendorDir . '/api/php_services/src/Ksy/Ksyun.php',
'Api\\PhpServices\\LifeAccount\\Account' => $vendorDir . '/api/php_services/src/LifeAccount/Account.php',
......@@ -73,11 +74,13 @@ return array(
'App\\Exception\\custom\\CodeSpecialException' => $baseDir . '/application/exception/custom/CodeSpecialException.php',
'App\\Exception\\custom\\GoodsException' => $baseDir . '/application/exception/custom/GoodsException.php',
'App\\Exception\\custom\\ParamException' => $baseDir . '/application/exception/custom/ParamException.php',
'App\\Exception\\custom\\ShopException' => $baseDir . '/application/exception/custom/ShopException.php',
'App\\Exception\\custom\\SignException' => $baseDir . '/application/exception/custom/SignException.php',
'App\\Exception\\custom\\TestException' => $baseDir . '/application/exception/custom/TestException.php',
'App\\Models\\demo\\mongo\\Test' => $baseDir . '/application/models/demo/mongo/Test.php',
'App\\Models\\demo\\mongo\\User' => $baseDir . '/application/models/demo/mongo/User.php',
'App\\Models\\demo\\mysql\\User' => $baseDir . '/application/models/demo/mysql/User.php',
'App\\Models\\distribution\\mysql\\Distribution' => $baseDir . '/application/models/distribution/mysql/Distribution.php',
'App\\Models\\goods\\mysql\\Category' => $baseDir . '/application/models/goods/mysql/Category.php',
'App\\Models\\goods\\mysql\\GoodsOperationRecord' => $baseDir . '/application/models/goods/mysql/GoodsOperationRecord.php',
'App\\Models\\goods\\mysql\\GoodsSku' => $baseDir . '/application/models/goods/mysql/GoodsSku.php',
......@@ -92,9 +95,11 @@ return array(
'App\\Services\\demo\\ElasticService' => $baseDir . '/application/services/demo/ElasticService.php',
'App\\Services\\demo\\MongoService' => $baseDir . '/application/services/demo/MongoService.php',
'App\\Services\\demo\\MysqlService' => $baseDir . '/application/services/demo/MysqlService.php',
'App\\Services\\distribution\\DistributionService' => $baseDir . '/application/services/distribution/DistributionService.php',
'App\\Services\\goods\\CategoryService' => $baseDir . '/application/services/goods/CategoryService.php',
'App\\Services\\goods\\ElasticService' => $baseDir . '/application/services/goods/ElasticService.php',
'App\\Services\\goods\\ElasticGoodService' => $baseDir . '/application/services/goods/ElasticGoodService.php',
'App\\Services\\goods\\GoodsService' => $baseDir . '/application/services/goods/GoodsService.php',
'App\\Services\\shop\\ShopService' => $baseDir . '/application/services/shop/ShopService.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'Daemon\\Test' => $baseDir . '/daemon/Test.php',
'Elasticsearch\\Client' => $vendorDir . '/elasticsearch/elasticsearch/src/Elasticsearch/Client.php',
......
......@@ -10,7 +10,7 @@ return array(
'ad155f8f1cf0d418fe49e248db8c661b' => $vendorDir . '/react/promise/src/functions_include.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'3a37ebac017bc098e9a86b35401e7a68' => $vendorDir . '/mongodb/mongodb/src/functions.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'8592c7b0947d8a0965a9e8c3d16f9c24' => $vendorDir . '/elasticsearch/elasticsearch/src/autoload.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'3a37ebac017bc098e9a86b35401e7a68' => $vendorDir . '/mongodb/mongodb/src/functions.php',
);
......@@ -11,9 +11,9 @@ class ComposerStaticInit48fd9e88279ffd9162a19bdedd5d5a0a
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'3a37ebac017bc098e9a86b35401e7a68' => __DIR__ . '/..' . '/mongodb/mongodb/src/functions.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'8592c7b0947d8a0965a9e8c3d16f9c24' => __DIR__ . '/..' . '/elasticsearch/elasticsearch/src/autoload.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'3a37ebac017bc098e9a86b35401e7a68' => __DIR__ . '/..' . '/mongodb/mongodb/src/functions.php',
);
public static $prefixLengthsPsr4 = array (
......@@ -152,6 +152,7 @@ class ComposerStaticInit48fd9e88279ffd9162a19bdedd5d5a0a
'Api\\PhpServices\\Daemon\\DaemonServiceInterface' => __DIR__ . '/..' . '/api/php_services/src/Daemon/DaemonServiceInterface.php',
'Api\\PhpServices\\Doc\\DocDynamic' => __DIR__ . '/..' . '/api/php_services/src/Doc/DocDynamic.php',
'Api\\PhpServices\\Idgen\\Idgen' => __DIR__ . '/..' . '/api/php_services/src/Idgen/Idgen.php',
'Api\\PhpServices\\Interaction\\InterDynamic' => __DIR__ . '/..' . '/api/php_services/src/Interaction/InterDynamic.php',
'Api\\PhpServices\\JwUser\\JwUser' => __DIR__ . '/..' . '/api/php_services/src/JwUser/JwUser.php',
'Api\\PhpServices\\Ksy\\Ksyun' => __DIR__ . '/..' . '/api/php_services/src/Ksy/Ksyun.php',
'Api\\PhpServices\\LifeAccount\\Account' => __DIR__ . '/..' . '/api/php_services/src/LifeAccount/Account.php',
......@@ -209,11 +210,13 @@ class ComposerStaticInit48fd9e88279ffd9162a19bdedd5d5a0a
'App\\Exception\\custom\\CodeSpecialException' => __DIR__ . '/../..' . '/application/exception/custom/CodeSpecialException.php',
'App\\Exception\\custom\\GoodsException' => __DIR__ . '/../..' . '/application/exception/custom/GoodsException.php',
'App\\Exception\\custom\\ParamException' => __DIR__ . '/../..' . '/application/exception/custom/ParamException.php',
'App\\Exception\\custom\\ShopException' => __DIR__ . '/../..' . '/application/exception/custom/ShopException.php',
'App\\Exception\\custom\\SignException' => __DIR__ . '/../..' . '/application/exception/custom/SignException.php',
'App\\Exception\\custom\\TestException' => __DIR__ . '/../..' . '/application/exception/custom/TestException.php',
'App\\Models\\demo\\mongo\\Test' => __DIR__ . '/../..' . '/application/models/demo/mongo/Test.php',
'App\\Models\\demo\\mongo\\User' => __DIR__ . '/../..' . '/application/models/demo/mongo/User.php',
'App\\Models\\demo\\mysql\\User' => __DIR__ . '/../..' . '/application/models/demo/mysql/User.php',
'App\\Models\\distribution\\mysql\\Distribution' => __DIR__ . '/../..' . '/application/models/distribution/mysql/Distribution.php',
'App\\Models\\goods\\mysql\\Category' => __DIR__ . '/../..' . '/application/models/goods/mysql/Category.php',
'App\\Models\\goods\\mysql\\GoodsOperationRecord' => __DIR__ . '/../..' . '/application/models/goods/mysql/GoodsOperationRecord.php',
'App\\Models\\goods\\mysql\\GoodsSku' => __DIR__ . '/../..' . '/application/models/goods/mysql/GoodsSku.php',
......@@ -228,9 +231,11 @@ class ComposerStaticInit48fd9e88279ffd9162a19bdedd5d5a0a
'App\\Services\\demo\\ElasticService' => __DIR__ . '/../..' . '/application/services/demo/ElasticService.php',
'App\\Services\\demo\\MongoService' => __DIR__ . '/../..' . '/application/services/demo/MongoService.php',
'App\\Services\\demo\\MysqlService' => __DIR__ . '/../..' . '/application/services/demo/MysqlService.php',
'App\\Services\\distribution\\DistributionService' => __DIR__ . '/../..' . '/application/services/distribution/DistributionService.php',
'App\\Services\\goods\\CategoryService' => __DIR__ . '/../..' . '/application/services/goods/CategoryService.php',
'App\\Services\\goods\\ElasticService' => __DIR__ . '/../..' . '/application/services/goods/ElasticService.php',
'App\\Services\\goods\\ElasticGoodService' => __DIR__ . '/../..' . '/application/services/goods/ElasticGoodService.php',
'App\\Services\\goods\\GoodsService' => __DIR__ . '/../..' . '/application/services/goods/GoodsService.php',
'App\\Services\\shop\\ShopService' => __DIR__ . '/../..' . '/application/services/shop/ShopService.php',
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'Daemon\\Test' => __DIR__ . '/../..' . '/daemon/Test.php',
'Elasticsearch\\Client' => __DIR__ . '/..' . '/elasticsearch/elasticsearch/src/Elasticsearch/Client.php',
......
......@@ -7,14 +7,14 @@
"source": {
"type": "git",
"url": "https://git.yidian-inc.com:8021/bp/php_services.git",
"reference": "95cfa288e4777d976f53787882e5c4ae9e7592e6"
"reference": "efdbb7f13f8184d60b56b0fb876b8868147162ac"
},
"require": {
"api/php_utils": "dev-master",
"perftools/php-profiler": "^0.18.0",
"php": ">=7.2"
},
"time": "2021-06-16T11:04:11+00:00",
"time": "2021-06-17T09:28:47+00:00",
"default-branch": true,
"type": "library",
"installation-source": "source",
......@@ -33,7 +33,7 @@
"source": {
"type": "git",
"url": "https://git.yidian-inc.com:8021/bp/php_utils.git",
"reference": "65546514336724128e7047b4a7704608f0400e80"
"reference": "474c015979f967bcd045224c7e4f47c206dcfad7"
},
"require": {
"elasticsearch/elasticsearch": "~7.0",
......@@ -45,7 +45,7 @@
"mongodb/mongodb": "1.4.3",
"php": ">=7.2"
},
"time": "2021-06-16T11:07:28+00:00",
"time": "2021-06-17T12:06:18+00:00",
"default-branch": true,
"type": "library",
"installation-source": "source",
......
......@@ -6,7 +6,7 @@
'aliases' =>
array (
),
'reference' => '84928268a3b67ce3c8f83c4e655aa5d05654c37b',
'reference' => 'aaa7a15562bb4388a4d9b639c7623edd5f44e2d7',
'name' => 'yidian/yaf_demo',
),
'versions' =>
......@@ -19,7 +19,7 @@
array (
0 => '9999999-dev',
),
'reference' => '95cfa288e4777d976f53787882e5c4ae9e7592e6',
'reference' => 'efdbb7f13f8184d60b56b0fb876b8868147162ac',
),
'api/php_utils' =>
array (
......@@ -29,7 +29,7 @@
array (
0 => '9999999-dev',
),
'reference' => '65546514336724128e7047b4a7704608f0400e80',
'reference' => '474c015979f967bcd045224c7e4f47c206dcfad7',
),
'elasticsearch/elasticsearch' =>
array (
......@@ -158,7 +158,7 @@
'aliases' =>
array (
),
'reference' => '84928268a3b67ce3c8f83c4e655aa5d05654c37b',
'reference' => 'aaa7a15562bb4388a4d9b639c7623edd5f44e2d7',
),
),
);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment