Commit 1cbec5f5 authored by luhongguang's avatar luhongguang

update:composer update

parent 3fb1e7bf
......@@ -12,7 +12,7 @@
"source": {
"type": "git",
"url": "https://git.yidian-inc.com:8021/bp/php_services.git",
"reference": "697463568a90156dd40ee8ff957c9cf189823c20"
"reference": "e7505fbd9f5dda96dd12fffee729a4851b4ab127"
},
"require": {
"api/php_utils": "dev-master",
......@@ -28,7 +28,7 @@
}
},
"description": "bp api php_services",
"time": "2021-07-26T03:47:20+00:00"
"time": "2021-07-28T13:33:13+00:00"
},
{
"name": "api/php_utils",
......@@ -36,7 +36,7 @@
"source": {
"type": "git",
"url": "https://git.yidian-inc.com:8021/bp/php_utils.git",
"reference": "04d22704930fc63806000f51914ce7bcd59d38ae"
"reference": "c9c90ab981f939bbf89d321d3101d58da1e797c6"
},
"require": {
"elasticsearch/elasticsearch": "~7.0",
......@@ -56,7 +56,7 @@
}
},
"description": "bp api php_utils",
"time": "2021-07-26T01:42:18+00:00"
"time": "2021-07-28T11:11:38+00:00"
},
{
"name": "bacon/bacon-qr-code",
......
......@@ -53,7 +53,8 @@ class Ks3Api
$genRes = HttpUtil::post($url, $params);
$end = microtime(true);
$totalTime = round(($end - $begin), 4) * 1000;
MonUtil::proxyMon($url, $genRes["response"]['code'], 'ks3api', $totalTime);
$resCode = $genRes["response"]['code'] === 0 ? 200 : $genRes["response"]['code'];
MonUtil::proxyMon($url, $resCode, 'ks3api', $totalTime);
return $genRes;
}
......@@ -90,7 +91,8 @@ class Ks3Api
$signatureRes = HttpUtil::post($url, $params);
$end = microtime(true);
$totalTime = round(($end - $begin), 4) * 1000;
MonUtil::proxyMon($url, $signatureRes["response"]['code'], 'ks3api', $totalTime);
$resCode = $signatureRes["response"]['code'] === 0 ? 200 : $signatureRes["response"]['code'];
MonUtil::proxyMon($url, $resCode, 'ks3api', $totalTime);
return $signatureRes;
}
......@@ -130,7 +132,8 @@ class Ks3Api
$encryptRes = HttpUtil::post($url, $params);
$end = microtime(true);
$totalTime = round(($end - $begin), 4) * 1000;
MonUtil::proxyMon($url, $encryptRes["response"]['code'], 'ks3api', $totalTime);
$resCode = $encryptRes["response"]['code'] === 0 ? 200 : $encryptRes["response"]['code'];
MonUtil::proxyMon($url, $resCode, 'ks3api', $totalTime);
return $encryptRes;
}
......@@ -163,7 +166,8 @@ class Ks3Api
$uploadRes = HttpUtil::post($url, $params);
$end = microtime(true);
$totalTime = round(($end - $begin), 4) * 1000;
MonUtil::proxyMon($url, $uploadRes["response"]['code'], 'ks3api', $totalTime);
$resCode = $uploadRes["response"]['code'] === 0 ? 200 : $uploadRes["response"]['code'];
MonUtil::proxyMon($url, $resCode, 'ks3api', $totalTime);
return $uploadRes;
}
......
<?php
namespace Api\PhpServices\Printer\Fei;
/**
* 飞蛾 打印实现类
*
* @author mengweifu
* @date 2021-7-25 14:00:00
*/
use Api\PhpUtils\Http\HttpUtil;
class FeiPrinter extends \Api\PhpServices\Printer\Printer
{
/**
* *必填*:账号名
*/
private const USER = "yonghui.chen@linkingcities.com";
/**
* *必填*: 飞鹅云后台注册账号后生成的UKEY 【备注:这不是填打印机的KEY】
*/
private const UKEY = "VjPMkB64QNuIIcgQ";
/**
* 飞鹅云打印 api前缀 不需要修改
*/
private const API = "http://api.feieyun.cn/Api/Open/";
/**
* 打印订单
*/
private const API_PRINT = "Open_printMsg";
/**
* 查询打印订单状态
*/
private const API_ORDER_STATUS = "Open_queryOrderState";
/**
* 获取某台打印机状态
*/
private const API_PRINTER_STATUS = "Open_queryPrinterStatus";
/**
* @param string $apiName api 名字
* @return array
*/
private function buildQuery(string $apiName) : array
{
$timestamp = time();
return [
'user' => self::USER,
'stime' => $timestamp,
'sig' => $this->signature(self::USER, self::UKEY, $timestamp),
'apiname' => $apiName
];
}
private function signature(String $user, String $uKey, int $sTime): string
{
return sha1($user . $uKey . $sTime);
}
/**
* 内部函数 查询
* @param string $apiName
* @param array $param
* @return array
*/
private function request(string $apiName,array $param): array
{
$param = $this->buildQuery($apiName) + $param;
return HttpUtil::post(self::API, http_build_query($param));
}
/**
* @inheritDoc
*/
public function addPrinter(array $param): bool
{
// TODO: Implement addPrinter() method.
}
/**
* @inheritDoc
*/
public function deletePrinter(string $printerId): bool
{
// TODO: Implement deletePrinter() method.
}
/**
* @inheritDoc
*/
public function getPrinterStatus(string $printerId): string
{
$res = $this->request(self::API_PRINTER_STATUS, [
'sn' => $printerId,
]);
if ($res['code'] == 0 && isset($res['response'])) {
if ($res['response']['ret'] == 0) {
return $res['response']['data'];
}
throw new Exception($res['response']['msg']);
}
throw new Exception("接口调用异常");
}
/**
* @inheritDoc
*/
public function printContent(string $printerId, array $content):string
{
$formattedContent = "";
$first = true;
foreach ($content as $row) {
$formattedRow = is_array($row) ? implode(' ', $row) : $row;
if ($first) {
$formattedContent .= "<CB>$formattedRow</CB><BR>";
}
else {
$formattedContent .= "$formattedRow<BR>";
}
$first = false;
}
$res = $this->request(self::API_PRINT, [
'sn' => $printerId,
'content' => $formattedContent,
'times' => 1,// 打印联数
]);
if ($res['code'] == 0 && isset($res['response'])) {
if ($res['response']['ret'] == 0) {
return $res['response']['data'];
}
throw new Exception($res['response']['msg']);
}
throw new Exception("接口调用异常");
}
/**
* @inheritDoc
*/
public function getOrderStatus(string $orderId): bool
{
$res = $this->request(self::API_ORDER_STATUS, [
'orderid' => $orderId,
]);
if ($res['code'] == 0 && isset($res['response'])) {
if ($res['response']['ret'] == 0) {
return (bool) $res['response']['data'];
}
throw new Exception($res['response']['msg']);
}
throw new Exception("接口调用异常");
}
}
\ No newline at end of file
<?php
namespace Api\PhpServices\Printer;
/**
* 打印抽象类
*
* @author mengweifu
* @date 2021-7-25 14:00:00
*/
abstract class Printer
{
/**
* 添加打印机
* @param array $param
* @return bool
*/
abstract public function addPrinter(array $param): bool;
/**
* 删除打印机
* @param string $printerId
* @return bool
*/
abstract public function deletePrinter(string $printerId): bool;
/**
* 获取打印机状态
* @param string $printerId
* @return string 状态描述
*/
abstract public function getPrinterStatus(string $printerId): string;
/**
* 打印
* @param string $printerId
* @param array $content 要打印的内容 支持一位数组 二维数组
* @return string 打印OrderID, ID
*/
abstract public function printContent(string $printerId, array $content): string;
/**
* 查询打印状态
* @param string $orderId 为printContent 返回
* @return bool
*/
abstract public function getOrderStatus(string $orderId): bool;
}
\ No newline at end of file
<?php
namespace Api\PhpServices\Printer;
/**
* 打印工厂类
*
* 如何使用:
* $content = [['aaa'], 'bbb'];
* $FeiPrinter = PrinterFactory::getPrinter('Fei');
* $res = $FeiPrinter->printContent('921617329', $content);
* $res = $FeiPrinter->getOrderStatus('921617329_20210725143642_699302110');
* $res = $FeiPrinter->getPrinterStatus('921617329');
* @author mengweifu
* @date 2021-7-25 14:00:00
*/
class PrinterFactory
{
/**
* 获取打印实现类
* @param string $printerName
* @return mixed
* @throws \Exception
*/
public static function getPrinter(string $printerName) : Printer
{
if (! file_exists(__DIR__ .DIRECTORY_SEPARATOR. $printerName. DIRECTORY_SEPARATOR . $printerName . 'Printer.php')) {
throw new \Exception("相应printer未找到");
}
$printerClass = "Api\\PhpServices\\Printer\\${printerName}\\${printerName}Printer";
return new $printerClass;
}
}
\ No newline at end of file
<?php
namespace Api\PhpServices\Wechat;
use Api\PhpUtils\Http\HttpUtil;
use App\Exception\custom\CodeSpecialException;
class Msg
{
/**
* 发送微信模版消息
* @param $user_id 简网用户id
* @param $app_id 微信公众号或者小程序appid
* @param $template_id 模版id
* @param $page_url 跳转页面
* @param $type 公众号或者小程序
* @param $param = [] 数组,多个参数传值
*/
public static function send($user_id, $app_id, $template_id, $page_url, $type, $param = [])
{
$url = config('interface', 'interaction.index.wechat');
if (!$url) {
throw new CodeSpecialException("failed");
}
$params = [
'user_id' => $user_id,
'app_id' => $app_id,
'template_id' => $template_id,
'page_url' => $page_url,
'type' => $type,
'params' => $param
];
$msg = HttpUtil::get($url, $params);
if (!$msg) {
throw new CodeSpecialException("timeout");
}
if (!empty($msg) && isset($msg['response']['code']) && $msg['response']['code'] == 0) {
return true;
} else {
return $msg['response'];
}
}
}
use Api\PhpServices\Wechat\Msg;
......@@ -158,10 +158,7 @@ abstract class MysqlClusterBase
}
// 读取配置文件内容
self::$iniConf = config('mysql', static::CONFIG_INDEX);
if (!self::$iniConf) {
throw new \Exception('mysql config not exist');
}
self::loadCfg();
// 获取库分片索引
$dbShardingIndex = self::getDatabaseShardingIndex();
......@@ -198,7 +195,8 @@ abstract class MysqlClusterBase
}
}
$end_time = microtime(true);
MonUtil::dbMon(self::$dbCurrentConnect['server'].'_'.self::$dbCurrentConnect['port'] ?? 'unknow_mysql', $method, 'mysql', $end_time-$start_time);
list($dbServer, $dbPort) = self::getDbServerPort($type, $dbShardingIndex);
MonUtil::dbMon($dbServer.'_'.$dbPort, $method, 'mysql', $end_time-$start_time);
return self::formatResult($method, $arguments);
}
......@@ -255,9 +253,11 @@ abstract class MysqlClusterBase
*
* @param string $type 读或写类型
* @return void
* @throws \Exception
*/
private static function getDbServerPort($type, $dbShardingIndex)
{
self::loadCfg();
$server = '';
$port = 0;
$host = self::$iniConf[$type]['host'];
......@@ -306,8 +306,12 @@ abstract class MysqlClusterBase
* 获取数据库分片数量
*
* @return integer
* @throws \Exception
*/
private static function getDbShardingCount() {
self::loadCfg();
$host = self::$iniConf[static::WRITE]['host'];
$hostList = explode(',', $host);
self::$dbShardingCount = count($hostList);
......@@ -318,13 +322,21 @@ abstract class MysqlClusterBase
*
* @return array
*/
private static function getDatabaseShardingIndex()
protected static function getDatabaseShardingIndex($dbShardingColumnValue = 0, $dbShardingCompatColumnValue = 0)
{
// 未使用分库
if (!static::SHARDING_DATABASE) {
return 0;
}
if(!empty($dbShardingColumnValue)) {
self::$dbShardingColumnValue = $dbShardingColumnValue;
}
if(!empty($dbShardingCompatColumnValue)) {
self::$dbShardingCompatColumnValue = $dbShardingCompatColumnValue;
}
self::getDbShardingCount();
$dbShardingIndex = 0;
......@@ -384,9 +396,12 @@ abstract class MysqlClusterBase
* 获取ini中的option配置,必须用\PDO::ATTR_STRINGIFY_FETCHES对应的int数值
*
* @return array
* @throws \Exception
*/
public static function getDbOptions()
{
self::loadCfg();
$options = [];
if (isset(self::$iniConf['options'])) {
foreach (self::$iniConf['options'] as $item) {
......@@ -562,6 +577,21 @@ abstract class MysqlClusterBase
return false;
}
/**
* @param bool $flush
* @throws \Exception
* 加载配置文件,支持强更新
*/
private static function loadCfg($flush = false) {
if($flush || empty(self::$iniConf)) {
//重新加载 ini
self::$iniConf = config('mysql', static::CONFIG_INDEX);
if (!self::$iniConf) {
throw new \Exception('mysql yaconf ini config not exist');
}
}
}
/**
* 格式化返回结果
*
......@@ -618,6 +648,7 @@ abstract class MysqlClusterBase
*
* @param int $dbShardingColumnValue
* @return bool
* @throws \Exception
*/
public static function beginTransaction($dbShardingColumnValue = 0, $dbShardingCompatColumnValue = 0)
{
......@@ -625,10 +656,7 @@ abstract class MysqlClusterBase
self::$dbShardingCompatColumnValue = $dbShardingCompatColumnValue;
// 读取配置文件内容
self::$iniConf = config('mysql', static::CONFIG_INDEX);
if (!self::$iniConf) {
throw new \Exception('mysql config not exist');
}
self::loadCfg();
// 获取库分片索引
self::$transationIndex = self::getDatabaseShardingIndex();
......@@ -717,15 +745,10 @@ abstract class MysqlClusterBase
* 获取所有分片连接
*
* @return array
* @throws \Exception
*/
public static function getWriteConnectionList()
{
// 读取配置文件内容
self::$iniConf = config('mysql', static::CONFIG_INDEX);
if (!self::$iniConf) {
throw new \Exception('mysql config not exist');
}
// 获取库分片数量
self::getDbShardingCount();
......@@ -740,15 +763,10 @@ abstract class MysqlClusterBase
* 获取所有分片连接
*
* @return array
* @throws \Exception
*/
public static function getReadConnectionList()
{
// 读取配置文件内容
self::$iniConf = config('mysql', static::CONFIG_INDEX);
if (!self::$iniConf) {
throw new \Exception('mysql config not exist');
}
// 获取库分片数量
self::getDbShardingCount();
......
......@@ -69,7 +69,7 @@ class RedisUtil
* @param array $options 其他参数数组,优先级高于yaconf中的相同配置
* @param string $options['serverRegion'] 服务区域,不同数据中心
* @param bool $options['master'] 哨兵模式/主从模式,默认true使用主库,若使用从库值为false
* @param string $options['serializer'] 序列化选项,包括 none|php|igbinary, msgpack自己实现msgpack_pack|msgpack_unpack, incr等方法只能使用none,set等方法使用none不能存Array或Object
* @param string $options['serializer'] 序列化选项,包括 none|php|igbinary|json, msgpack自己实现msgpack_pack|msgpack_unpack, incr等方法只能使用none,set等方法使用none不能存Array或Object
* @param boolean $master
* @return mixed
*/
......@@ -368,10 +368,9 @@ class RedisUtil
case 'igbinary':
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY); // Use igBinary serialize/unserialize
break;
case 'msgpack':
// Undefined class constant 'SERIALIZER_MSGPACK'
// $this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_MSGPACK); // Use msgpack serialize/unserialize
// break;
case 'json':
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_JSON); // Use json serialize/unserialize
break;
default:
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE); // Don't serialize data
break;
......
......@@ -32,7 +32,7 @@ private static $installed = array (
'aliases' =>
array (
),
'reference' => '0e9bc7276a2d67047a7ac1eec490abe129b3c16b',
'reference' => '3fb1e7bfb44c282528c719c13beabd3eac4d9cff',
'name' => 'yidian/yaf_demo',
),
'versions' =>
......@@ -45,7 +45,7 @@ private static $installed = array (
array (
0 => '9999999-dev',
),
'reference' => '697463568a90156dd40ee8ff957c9cf189823c20',
'reference' => 'e7505fbd9f5dda96dd12fffee729a4851b4ab127',
),
'api/php_utils' =>
array (
......@@ -55,7 +55,7 @@ private static $installed = array (
array (
0 => '9999999-dev',
),
'reference' => '04d22704930fc63806000f51914ce7bcd59d38ae',
'reference' => 'c9c90ab981f939bbf89d321d3101d58da1e797c6',
),
'bacon/bacon-qr-code' =>
array (
......@@ -334,7 +334,7 @@ private static $installed = array (
'aliases' =>
array (
),
'reference' => '0e9bc7276a2d67047a7ac1eec490abe129b3c16b',
'reference' => '3fb1e7bfb44c282528c719c13beabd3eac4d9cff',
),
),
);
......
......@@ -22,6 +22,9 @@ return array(
'Api\\PhpServices\\Ksy\\Ksyun' => $vendorDir . '/api/php_services/src/Ksy/Ksyun.php',
'Api\\PhpServices\\LifeAccount\\Account' => $vendorDir . '/api/php_services/src/LifeAccount/Account.php',
'Api\\PhpServices\\Login\\Login' => $vendorDir . '/api/php_services/src/Login/Login.php',
'Api\\PhpServices\\Printer\\Fei\\FeiPrinter' => $vendorDir . '/api/php_services/src/Printer/Fei/FeiPrinter.php',
'Api\\PhpServices\\Printer\\Printer' => $vendorDir . '/api/php_services/src/Printer/Printer.php',
'Api\\PhpServices\\Printer\\PrinterFactory' => $vendorDir . '/api/php_services/src/Printer/PrinterFactory.php',
'Api\\PhpServices\\PushToken\\Android' => $vendorDir . '/api/php_services/src/PushToken/Android.php',
'Api\\PhpServices\\PushToken\\Base' => $vendorDir . '/api/php_services/src/PushToken/Base.php',
'Api\\PhpServices\\PushToken\\Ios' => $vendorDir . '/api/php_services/src/PushToken/Ios.php',
......@@ -35,6 +38,7 @@ return array(
'Api\\PhpServices\\Sms\\Sms' => $vendorDir . '/api/php_services/src/Sms/Sms.php',
'Api\\PhpServices\\Towerpro\\Towerpro' => $vendorDir . '/api/php_services/src/Towerpro/Towerpro.php',
'Api\\PhpServices\\Tuffy\\TuffyService' => $vendorDir . '/api/php_services/src/Tuffy/TuffyService.php',
'Api\\PhpServices\\Wechat\\Msg' => $vendorDir . '/api/php_services/src/Wechat/Msg.php',
'Api\\PhpServices\\XhProfiler\\XhMongo' => $vendorDir . '/api/php_services/src/XhProfiler/XhMongo.php',
'Api\\PhpServices\\XhProfiler\\XhProfilerService' => $vendorDir . '/api/php_services/src/XhProfiler/XhProfilerService.php',
'Api\\PhpServices\\XhProfiler\\Xhprof' => $vendorDir . '/api/php_services/src/XhProfiler/Xhprof.php',
......
......@@ -251,6 +251,9 @@ class ComposerStaticInit90e85a2e64f8339192f3e91b8700b9f2
'Api\\PhpServices\\Ksy\\Ksyun' => __DIR__ . '/..' . '/api/php_services/src/Ksy/Ksyun.php',
'Api\\PhpServices\\LifeAccount\\Account' => __DIR__ . '/..' . '/api/php_services/src/LifeAccount/Account.php',
'Api\\PhpServices\\Login\\Login' => __DIR__ . '/..' . '/api/php_services/src/Login/Login.php',
'Api\\PhpServices\\Printer\\Fei\\FeiPrinter' => __DIR__ . '/..' . '/api/php_services/src/Printer/Fei/FeiPrinter.php',
'Api\\PhpServices\\Printer\\Printer' => __DIR__ . '/..' . '/api/php_services/src/Printer/Printer.php',
'Api\\PhpServices\\Printer\\PrinterFactory' => __DIR__ . '/..' . '/api/php_services/src/Printer/PrinterFactory.php',
'Api\\PhpServices\\PushToken\\Android' => __DIR__ . '/..' . '/api/php_services/src/PushToken/Android.php',
'Api\\PhpServices\\PushToken\\Base' => __DIR__ . '/..' . '/api/php_services/src/PushToken/Base.php',
'Api\\PhpServices\\PushToken\\Ios' => __DIR__ . '/..' . '/api/php_services/src/PushToken/Ios.php',
......@@ -264,6 +267,7 @@ class ComposerStaticInit90e85a2e64f8339192f3e91b8700b9f2
'Api\\PhpServices\\Sms\\Sms' => __DIR__ . '/..' . '/api/php_services/src/Sms/Sms.php',
'Api\\PhpServices\\Towerpro\\Towerpro' => __DIR__ . '/..' . '/api/php_services/src/Towerpro/Towerpro.php',
'Api\\PhpServices\\Tuffy\\TuffyService' => __DIR__ . '/..' . '/api/php_services/src/Tuffy/TuffyService.php',
'Api\\PhpServices\\Wechat\\Msg' => __DIR__ . '/..' . '/api/php_services/src/Wechat/Msg.php',
'Api\\PhpServices\\XhProfiler\\XhMongo' => __DIR__ . '/..' . '/api/php_services/src/XhProfiler/XhMongo.php',
'Api\\PhpServices\\XhProfiler\\XhProfilerService' => __DIR__ . '/..' . '/api/php_services/src/XhProfiler/XhProfilerService.php',
'Api\\PhpServices\\XhProfiler\\Xhprof' => __DIR__ . '/..' . '/api/php_services/src/XhProfiler/Xhprof.php',
......
......@@ -7,7 +7,7 @@
"source": {
"type": "git",
"url": "https://git.yidian-inc.com:8021/bp/php_services.git",
"reference": "697463568a90156dd40ee8ff957c9cf189823c20"
"reference": "e7505fbd9f5dda96dd12fffee729a4851b4ab127"
},
"require": {
"api/php_utils": "dev-master",
......@@ -15,7 +15,7 @@
"perftools/php-profiler": "^0.18.0",
"php": "7.2.*"
},
"time": "2021-07-26T03:47:20+00:00",
"time": "2021-07-28T13:33:13+00:00",
"default-branch": true,
"type": "library",
"installation-source": "source",
......@@ -34,7 +34,7 @@
"source": {
"type": "git",
"url": "https://git.yidian-inc.com:8021/bp/php_utils.git",
"reference": "04d22704930fc63806000f51914ce7bcd59d38ae"
"reference": "c9c90ab981f939bbf89d321d3101d58da1e797c6"
},
"require": {
"elasticsearch/elasticsearch": "~7.0",
......@@ -46,7 +46,7 @@
"mongodb/mongodb": "1.4.3",
"php": "7.2.*"
},
"time": "2021-07-26T01:42:18+00:00",
"time": "2021-07-28T11:11:38+00:00",
"default-branch": true,
"type": "library",
"installation-source": "source",
......
......@@ -6,7 +6,7 @@
'aliases' =>
array (
),
'reference' => '0e9bc7276a2d67047a7ac1eec490abe129b3c16b',
'reference' => '3fb1e7bfb44c282528c719c13beabd3eac4d9cff',
'name' => 'yidian/yaf_demo',
),
'versions' =>
......@@ -19,7 +19,7 @@
array (
0 => '9999999-dev',
),
'reference' => '697463568a90156dd40ee8ff957c9cf189823c20',
'reference' => 'e7505fbd9f5dda96dd12fffee729a4851b4ab127',
),
'api/php_utils' =>
array (
......@@ -29,7 +29,7 @@
array (
0 => '9999999-dev',
),
'reference' => '04d22704930fc63806000f51914ce7bcd59d38ae',
'reference' => 'c9c90ab981f939bbf89d321d3101d58da1e797c6',
),
'bacon/bacon-qr-code' =>
array (
......@@ -308,7 +308,7 @@
'aliases' =>
array (
),
'reference' => '0e9bc7276a2d67047a7ac1eec490abe129b3c16b',
'reference' => '3fb1e7bfb44c282528c719c13beabd3eac4d9cff',
),
),
);
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