Generate wechat sign.

@author yansongda <me@yansongda.cn>

@param array $data

@throws InvalidArgumentException

@return string
16573
public static function generateSign($data): string
    {
        $key = self::$instance->key;

        if (is_null($key)) {
            throw new InvalidArgumentException('Missing Wechat Config -- [key]');
        }

        ksort($data);

        $string = md5(self::getSignContent($data).'&key='.$key);

        Log::debug('Wechat Generate Sign Before UPPER', [$data, $string]);

        return strtoupper($string);
    }
261528
function pack(array $data)
    {
        if (count($data) != count($this->fileds))
        {
            throw new InvalidParam("{$this->class}: invalid data.");
        }

        $_binStr = '';
        foreach ($this->fileds as $k => $field)
        {
            if (!isset($data[$k]))
            {
                throw new InvalidParam("{$this->class}: item[key=$k] is not exists.");
            }
            /**
             * @var $field Field
             */
            switch ($field->type)
            {
                case Field::INT:
                    $value = intval($data[$k]);
                    switch ($field->size)
                    {
                        case 1:
                            $_binStr .= pack($field->signed ? 'c' : 'C', $value);
                            break;
                        case 2:
                            if ($this->convertBigEndian)
                            {
                                //网络字节序只有无符号的编码方式
                                $_binStr .= pack('n', $value);
                            }
                            else
                            {
                                $_binStr .= pack($field->signed ? 's' : 'S', $value);
                            }
                            break;
                        case 4:
                            if ($this->convertBigEndian)
                            {
                                //网络字节序只有无符号的编码方式
                                $_binStr .= pack('N', $value);
                            }
                            else
                            {
                                $_binStr .= pack($field->signed ? 'l' : 'L', $value);
                            }
                            break;
                        case 8:
                            if ($this->convertBigEndian)
                            {
                                //网络字节序只有无符号的编码方式
                                $_binStr .= pack('J', $value);
                            }
                            else
                            {
                                $_binStr .= pack($field->signed ? 'q' : 'Q', $value);
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                case Field::FLOAT:
                    $value = floatval($data[$k]);
                    $_binStr .= pack($field->size == 4 ? 'f' : 'd', $value);
                    break;
                case Field::CHAR:
                    $value = strval($data[$k]);
                    //C字符串末尾必须为\0，最大只能保存(size-1)个字节
                    if (strlen($value) > $field->size - 1)
                    {
                        throw new InvalidParam("string is too long.");
                    }
                    $_binStr .=  pack('a' . ($field->size - 1) . 'x', $value);
                    break;
                /**
                 * 结构体类型
                 */
                case Field::STRUCT:
                    //参数必须为数组，个数必须与结构体的字段数量一致
                    if (!is_array($data[$k]) or count($data[$k]) != count($field->struct->fileds))
                    {
                        throw new InvalidParam("struct size invalid.");
                    }
                    $_binStr .= $field->struct->pack($data[$k]);
                    break;
                default:
                    break;
            }
        }

        return $_binStr;
    }
817608
static public function encode($data)
	{
		if (is_array($data) || (is_object($data) && !method_exists($data, '_toString')))
		{
			throw new \InvalidArgumentException(__CLASS__ . ' can not handle an array or non-stringable object.');
		}

		return $data;
	}
77750
public function createCard(array $data)
    {
        $result = $this->wechat->httpRaw(self::WECHAT_CARD_CREATE_PREFIX, $data, [
            'access_token' => $this->wechat->getAccessToken()
        ]);
        return isset($result['errmsg']) && $result['errmsg'] === 'ok' ? $result['card_id'] : false;
    }
1292865
protected function createToken($data)
    {
        $key = self::getJwtKey();

        $token = array(
            "iat" => time(),
            "provider" => get_class($this),
            "category" => $this->category,
            "data" => $data
        );

        $jwt = JWT::encode($token, $key);

        return $jwt;
    }
587165
public function updateUser(array $data)
    {
        $result = $this->httpRaw(self::WECHAT_USER_UPDATE_PREFIX, $data, [
            'access_token' => $this->getAccessToken()
        ]);
        return isset($result['errcode']) && !$result['errcode'];
    }
1244492
private function signOpenSSL($data)
    {
        $algo = OPENSSL_ALGO_SHA1;
        if (!empty($this->cryptParams['digest'])) {
            $algo = $this->cryptParams['digest'];
        }
        if (!openssl_sign($data, $signature, $this->key, $algo)) {
            throw new Exception('Failure Signing Data: ' . openssl_error_string() . ' - ' . $algo);
        }
        return $signature;
    }
394345
private function resolveMainLanguageCode($data): string
    {
        if (!$data instanceof ContentUpdateData && !$data instanceof ContentCreateData) {
            throw new InvalidArgumentException(
                '$data',
                'expected type of ContentUpdateData or ContentCreateData'
            );
        }

        return $data->isNew()
            ? $data->mainLanguageCode
            : $data->contentDraft->getVersionInfo()->getContentInfo()->mainLanguageCode;
    }
1079938
public function updateCard(array $data)
    {
        $result = $this->wechat->httpPost(self::WECHAT_CARD_LIST_GET_PREFIX, $data, [
            'access_token' => $this->wechat->getAccessToken()
        ]);
        return isset($result['errmsg']) && $result['errmsg'] === 'ok';
    }
1256075
public function createUser(array $data)
    {
        $result = $this->httpRaw(self::WECHAT_USER_CREATE_PREFIX, $data, [
            'access_token' => $this->getAccessToken()
        ]);
        return isset($result['errcode']) && ($result['errcode'] ? $this->dump([$data,$result,$this->getAccessToken()]) : !$result['errcode']);
    }
105281
public function setData($data = array())
    {
        // Encode <, >, ', &, and " for RFC4627-compliant JSON, which may also be embedded into HTML.
        $this->data = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);

        if (JSON_ERROR_NONE !== json_last_error()) {
            throw new \InvalidArgumentException($this->transformJsonError());
        }

        return $this->update();
    }
155698
public function updateUser(array $data)
    {
        $result = $this->httpRaw(self::WECHAT_USER_UPDATE_PREFIX, $data, [
            'access_token' => $this->getAccessToken()
        ]);
        return isset($result['errcode']) && ($result['errcode'] ? $this->dump([$data,$result,$this->getAccessToken()]) : !$result['errcode']);
    }
1125067
public static function toXml($data): string
    {
        if (!is_array($data) || count($data) <= 0) {
            throw new InvalidArgumentException('Convert To Xml Error! Invalid Array!');
        }

        $xml = '<xml>';
        foreach ($data as $key => $val) {
            $xml .= is_numeric($val) ? '<'.$key.'>'.$val.'</'.$key.'>' :
                                       '<'.$key.'><![CDATA['.$val.']]></'.$key.'>';
        }
        $xml .= '</xml>';

        return $xml;
    }
540251
public static function buildDeEmojiData(array $data)
    {
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $data[$key] = self::buildDeEmojiData($value);
            } elseif (is_string($value)) {
                $data[$key] = self::emojiDecode($value);
            } else {
                $data[$key] = $value;
            }
        }
        return $data;
    }
412714
public function verifySignature(array $data)
    {
        $signedData = array_intersect_key($data, array_flip(self::$validResponseParams));
        ksort($signedData);

        $queryString = $this->buildQueryString($signedData);
        $signature = base64_encode(hash_hmac('sha1', $queryString, $this->clientSecret, true));

        return hash_equals($signature, $data['h']);
    }
880850
public function updateDeliverTemplate(array $data)
    {
        $result = $this->wechat->httpRaw(self::WECHAT_DELIVERY_TEMPLATE_UPDATE_PREFIX, $data, [
            'access_token' => $this->wechat->getAccessToken()
        ]);
        return isset($result['errmsg']) && $result['errmsg'] == 'success';
    }
787581
public static function fromArray(array $data): self
    {
        if (!array_key_exists('token', $data)) {
            throw new InvalidArgumentException('Missing field "token"');
        }

        $message = self::create($data['token']);

        if ($data['data'] ?? null) {
            $message = $message->withData($data['data']);
        }

        if ($data['notification'] ?? null) {
            $message = $message->withNotification(Notification::fromArray($data['notification']));
        }

        if ($data['android'] ?? null) {
            $message = $message->withAndroidConfig(AndroidConfig::fromArray($data['android']));
        }

        if ($data['apns'] ?? null) {
            $message = $message->withApnsConfig(ApnsConfig::fromArray($data['apns']));
        }

        if ($data['webpush'] ?? null) {
            $message = $message->withWebPushConfig(WebPushConfig::fromArray($data['webpush']));
        }

        return $message;
    }