硕顺crm后台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

167 lines
4.1 KiB

<?php
namespace WeWork;
use SimpleXMLElement;
use Symfony\Component\HttpFoundation\Request;
use WeWork\Crypt\WXBizMsgCrypt;
use WeWork\Message\ReplyMessageInterface;
class Callback
{
/**
* @var Request
*/
private $request;
/**
* @var WXBizMsgCrypt
*/
private $crypt;
/**
* @param Request $request
* @param WXBizMsgCrypt $crypt
*/
public function __construct(Request $request, WXBizMsgCrypt $crypt)
{
$this->request = $request;
$this->crypt = $crypt;
}
/**
* @param string $key
* @return mixed
*/
public function get(string $key)
{
if (!$this->request->getContent()) {
return null;
}
if (!$this->request->attributes->has($key)) {
$this->initializeAttribute();
}
return $this->request->attributes->get($key);
}
/**
* @return void
*/
private function initializeAttribute(): void
{
$data = '';
$this->crypt->DecryptMsg(
$this->request->query->get('msg_signature'),
$this->request->query->get('timestamp'),
$this->request->query->get('nonce'),
$this->request->getContent(),
$data
);
if ($data) {
$xml = new SimpleXMLElement($data);
foreach ($xml as $key => $value) {
$this->request->attributes->set("$key", "$value");
}
}
}
/**
* @return string
*/
private function decryptEchoStr(): string
{
$plainText = '';
$this->crypt->VerifyURL(
$this->request->query->get('msg_signature'),
$this->request->query->get('timestamp'),
$this->request->query->get('nonce'),
$this->request->query->get('echostr'),
$plainText
);
return $plainText;
}
/**
* @param ReplyMessageInterface $replyMessage
* @return string
*/
public function reply(ReplyMessageInterface $replyMessage): string
{
if ($this->request->query->has('echostr')) {
return $this->decryptEchoStr();
} else {
return $this->encryptReply($this->buildReply($replyMessage));
}
}
/**
* @param string $reply
* @return string
*/
private function encryptReply(string $reply): string
{
$cipherText = '';
$this->crypt->EncryptMsg(
$reply,
$this->request->query->get('timestamp'),
$this->request->query->get('nonce'),
$cipherText
);
return $cipherText;
}
/**
* @param ReplyMessageInterface $replyMessage
* @return string
*/
private function buildReply(ReplyMessageInterface $replyMessage): string
{
$reply = $replyMessage->formatForReply();
$reply['ToUserName'] = $this->request->attributes->get('FromUserName');
$reply['FromUserName'] = $this->request->attributes->get('ToUserName');
$reply['CreateTime'] = (int)$this->request->attributes->get('CreateTime');
$element = new SimpleXMLElement('<xml/>');
$this->arrayToXml($reply, $element);
$dom = dom_import_simplexml($element);
return $dom->ownerDocument->saveXML($dom->ownerDocument->documentElement);
}
/**
* @param array $data
* @param SimpleXMLElement $element
* @return void
*/
private function arrayToXml(array $data, SimpleXMLElement &$element): void
{
foreach ($data as $key => $value) {
if (is_numeric($key)) {
$key = 'item';
}
if (is_array($value)) {
$subNode = $element->addChild($key);
$this->arrayToXml($value, $subNode);
} elseif (is_string($value)) {
$node = dom_import_simplexml($element->addChild($key));
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($value));
} else {
$element->addChild($key, $value);
}
}
}
}