初始化仓库

This commit is contained in:
wangxiaowei
2025-04-22 14:09:52 +08:00
commit 8b100110bb
5155 changed files with 664201 additions and 0 deletions

View File

@ -0,0 +1,93 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use Psr\Http\Message\RequestInterface;
abstract class AbstractLocation implements RequestLocationInterface
{
/** @var string */
protected $locationName;
/**
* Set the name of the location
*/
public function __construct($locationName)
{
$this->locationName = $locationName;
}
/**
* @return RequestInterface
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
) {
return $request;
}
/**
* @return RequestInterface
*/
public function after(
CommandInterface $command,
RequestInterface $request,
Operation $operation
) {
return $request;
}
/**
* Prepare (filter and set desired name for request item) the value for
* request.
*
* @param mixed $value
*
* @return array|mixed
*/
protected function prepareValue($value, Parameter $param)
{
return is_array($value)
? $this->resolveRecursively($value, $param)
: $param->filter($value);
}
/**
* Recursively prepare and filter nested values.
*
* @param array $value Value to map
* @param Parameter $param Parameter related to the current key.
*
* @return array Returns the mapped array
*/
protected function resolveRecursively(array $value, Parameter $param)
{
foreach ($value as $name => &$v) {
switch ($param->getType()) {
case 'object':
if ($subParam = $param->getProperty($name)) {
$key = $subParam->getWireName();
$value[$key] = $this->prepareValue($v, $subParam);
if ($name != $key) {
unset($value[$name]);
}
} elseif ($param->getAdditionalProperties() instanceof Parameter) {
$v = $this->prepareValue($v, $param->getAdditionalProperties());
}
break;
case 'array':
if ($items = $param->getItems()) {
$v = $this->prepareValue($v, $items);
}
break;
}
}
return $param->filter($value);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Parameter;
use GuzzleHttp\Psr7;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
/**
* Adds a body to a request
*/
class BodyLocation extends AbstractLocation
{
/**
* Set the name of the location
*
* @param string $locationName
*/
public function __construct($locationName = 'body')
{
parent::__construct($locationName);
}
/**
* @return MessageInterface
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
) {
$oldValue = $request->getBody()->getContents();
$value = $command[$param->getName()];
$value = $param->getName().'='.$param->filter($value);
if ($oldValue !== '') {
$value = $oldValue.'&'.$value;
}
return $request->withBody(Psr7\Utils::streamFor($value));
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;
/**
* Add form_params to a request
*/
class FormParamLocation extends AbstractLocation
{
/** @var string */
protected $contentType = 'application/x-www-form-urlencoded; charset=utf-8';
/** @var array */
protected $formParamsData = [];
/**
* Set the name of the location
*
* @param string $locationName
*/
public function __construct($locationName = 'formParam')
{
parent::__construct($locationName);
}
/**
* @return RequestInterface
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
) {
$this->formParamsData['form_params'][$param->getWireName()] = $this->prepareValue(
$command[$param->getName()],
$param
);
return $request;
}
/**
* @return RequestInterface
*/
public function after(
CommandInterface $command,
RequestInterface $request,
Operation $operation
) {
$data = $this->formParamsData;
$this->formParamsData = [];
$modify = [];
// Add additional parameters to the form_params array
$additional = $operation->getAdditionalParameters();
if ($additional && $additional->getLocation() == $this->locationName) {
foreach ($command->toArray() as $key => $value) {
if (!$operation->hasParam($key)) {
$data['form_params'][$key] = $this->prepareValue($value, $additional);
}
}
}
$body = http_build_query($data['form_params'], '', '&');
$modify['body'] = Psr7\Utils::streamFor($body);
$modify['set_headers']['Content-Type'] = $this->contentType;
return Psr7\Utils::modifyRequest($request, $modify);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
/**
* Request header location
*/
class HeaderLocation extends AbstractLocation
{
/**
* Set the name of the location
*
* @param string $locationName
*/
public function __construct($locationName = 'header')
{
parent::__construct($locationName);
}
/**
* @return MessageInterface
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
) {
$value = $command[$param->getName()];
return $request->withHeader($param->getWireName(), $param->filter($value));
}
/**
* @return RequestInterface
*/
public function after(
CommandInterface $command,
RequestInterface $request,
Operation $operation
) {
/** @var Parameter $additional */
$additional = $operation->getAdditionalParameters();
if ($additional && ($additional->getLocation() === $this->locationName)) {
foreach ($command->toArray() as $key => $value) {
if (!$operation->hasParam($key)) {
$request = $request->withHeader($key, $additional->filter($value));
}
}
}
return $request;
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use GuzzleHttp\Psr7;
use GuzzleHttp\Utils;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
/**
* Creates a JSON document
*/
class JsonLocation extends AbstractLocation
{
/** @var string Whether or not to add a Content-Type header when JSON is found */
private $jsonContentType;
/** @var array */
private $jsonData;
/**
* @param string $locationName Name of the location
* @param string $contentType Content-Type header to add to the request if
* JSON is added to the body. Pass an empty string to omit.
*/
public function __construct($locationName = 'json', $contentType = 'application/json')
{
parent::__construct($locationName);
$this->jsonContentType = $contentType;
}
/**
* @return RequestInterface
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
) {
$this->jsonData[$param->getWireName()] = $this->prepareValue(
$command[$param->getName()],
$param
);
return $request->withBody(Psr7\Utils::streamFor(Utils::jsonEncode($this->jsonData)));
}
/**
* @return MessageInterface
*/
public function after(
CommandInterface $command,
RequestInterface $request,
Operation $operation
) {
$data = $this->jsonData;
$this->jsonData = [];
// Add additional parameters to the JSON document
$additional = $operation->getAdditionalParameters();
if ($additional && ($additional->getLocation() === $this->locationName)) {
foreach ($command->toArray() as $key => $value) {
if (!$operation->hasParam($key)) {
$data[$key] = $this->prepareValue($value, $additional);
}
}
}
// Don't overwrite the Content-Type if one is set
if ($this->jsonContentType && !$request->hasHeader('Content-Type')) {
$request = $request->withHeader('Content-Type', $this->jsonContentType);
}
return $request->withBody(Psr7\Utils::streamFor(Utils::jsonEncode($data)));
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;
/**
* Adds POST files to a request
*/
class MultiPartLocation extends AbstractLocation
{
/** @var string */
protected $contentType = 'multipart/form-data; boundary=';
/** @var array */
protected $multipartData = [];
/**
* Set the name of the location
*
* @param string $locationName
*/
public function __construct($locationName = 'multipart')
{
parent::__construct($locationName);
}
/**
* @return RequestInterface
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
) {
$this->multipartData[] = [
'name' => $param->getWireName(),
'contents' => $this->prepareValue($command[$param->getName()], $param),
];
return $request;
}
/**
* @return RequestInterface
*/
public function after(
CommandInterface $command,
RequestInterface $request,
Operation $operation
) {
$data = $this->multipartData;
$this->multipartData = [];
$modify = [];
$body = new Psr7\MultipartStream($data);
$modify['body'] = Psr7\Utils::streamFor($body);
$request = Psr7\Utils::modifyRequest($request, $modify);
if ($request->getBody() instanceof Psr7\MultipartStream) {
// Use a multipart/form-data POST if a Content-Type is not set.
$request->withHeader('Content-Type', $this->contentType.$request->getBody()->getBoundary());
}
return $request;
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use GuzzleHttp\Command\Guzzle\QuerySerializer\QuerySerializerInterface;
use GuzzleHttp\Command\Guzzle\QuerySerializer\Rfc3986Serializer;
use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;
/**
* Adds query string values to requests
*/
class QueryLocation extends AbstractLocation
{
/**
* @var QuerySerializerInterface
*/
private $querySerializer;
/**
* Set the name of the location
*
* @param string $locationName
*/
public function __construct($locationName = 'query', QuerySerializerInterface $querySerializer = null)
{
parent::__construct($locationName);
$this->querySerializer = $querySerializer ?: new Rfc3986Serializer();
}
/**
* @return RequestInterface
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
) {
$uri = $request->getUri();
$query = Psr7\Query::parse($uri->getQuery());
$query[$param->getWireName()] = $this->prepareValue(
$command[$param->getName()],
$param
);
$uri = $uri->withQuery($this->querySerializer->aggregate($query));
return $request->withUri($uri);
}
/**
* @return RequestInterface
*/
public function after(
CommandInterface $command,
RequestInterface $request,
Operation $operation
) {
$additional = $operation->getAdditionalParameters();
if ($additional && $additional->getLocation() == $this->locationName) {
foreach ($command->toArray() as $key => $value) {
if (!$operation->hasParam($key)) {
$uri = $request->getUri();
$query = Psr7\Query::parse($uri->getQuery());
$query[$key] = $this->prepareValue(
$value,
$additional
);
$uri = $uri->withQuery($this->querySerializer->aggregate($query));
$request = $request->withUri($uri);
}
}
}
return $request;
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use Psr\Http\Message\RequestInterface;
/**
* Handles locations specified in a service description
*/
interface RequestLocationInterface
{
/**
* Visits a location for each top-level parameter
*
* @param CommandInterface $command Command being prepared
* @param RequestInterface $request Request being modified
* @param Parameter $param Parameter being visited
*
* @return RequestInterface Modified request
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
);
/**
* Called when all of the parameters of a command have been visited.
*
* @param CommandInterface $command Command being prepared
* @param RequestInterface $request Request being modified
* @param Operation $operation Operation being serialized
*
* @return RequestInterface Modified request
*/
public function after(
CommandInterface $command,
RequestInterface $request,
Operation $operation
);
}

View File

@ -0,0 +1,310 @@
<?php
namespace GuzzleHttp\Command\Guzzle\RequestLocation;
use GuzzleHttp\Command\CommandInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;
/**
* Creates an XML document
*/
class XmlLocation extends AbstractLocation
{
/** @var \XMLWriter XML writer resource */
private $writer;
/** @var string Content-Type header added when XML is found */
private $contentType;
/** @var Parameter[] Buffered elements to write */
private $buffered = [];
/**
* @param string $locationName Name of the location
* @param string $contentType Set to a non-empty string to add a
* Content-Type header to a request if any XML content is added to the
* body. Pass an empty string to disable the addition of the header.
*/
public function __construct($locationName = 'xml', $contentType = 'application/xml')
{
parent::__construct($locationName);
$this->contentType = $contentType;
}
/**
* @return RequestInterface
*/
public function visit(
CommandInterface $command,
RequestInterface $request,
Parameter $param
) {
// Buffer and order the parameters to visit based on if they are
// top-level attributes or child nodes.
// @link https://github.com/guzzle/guzzle/pull/494
if ($param->getData('xmlAttribute')) {
array_unshift($this->buffered, $param);
} else {
$this->buffered[] = $param;
}
return $request;
}
/**
* @return RequestInterface
*/
public function after(
CommandInterface $command,
RequestInterface $request,
Operation $operation
) {
foreach ($this->buffered as $param) {
$this->visitWithValue(
$command[$param->getName()],
$param,
$operation
);
}
$this->buffered = [];
$additional = $operation->getAdditionalParameters();
if ($additional && $additional->getLocation() == $this->locationName) {
foreach ($command->toArray() as $key => $value) {
if (!$operation->hasParam($key)) {
$additional->setName($key);
$this->visitWithValue($value, $additional, $operation);
}
}
$additional->setName(null);
}
// If data was found that needs to be serialized, then do so
$xml = '';
if ($this->writer) {
$xml = $this->finishDocument($this->writer);
} elseif ($operation->getData('xmlAllowEmpty')) {
// Check if XML should always be sent for the command
$writer = $this->createRootElement($operation);
$xml = $this->finishDocument($writer);
}
if ($xml !== '') {
$request = $request->withBody(Psr7\Utils::streamFor($xml));
// Don't overwrite the Content-Type if one is set
if ($this->contentType && !$request->hasHeader('Content-Type')) {
$request = $request->withHeader('Content-Type', $this->contentType);
}
}
$this->writer = null;
return $request;
}
/**
* Create the root XML element to use with a request
*
* @param Operation $operation Operation object
*
* @return \XMLWriter
*/
protected function createRootElement(Operation $operation)
{
static $defaultRoot = ['name' => 'Request'];
// If no root element was specified, then just wrap the XML in 'Request'
$root = $operation->getData('xmlRoot') ?: $defaultRoot;
// Allow the XML declaration to be customized with xmlEncoding
$encoding = $operation->getData('xmlEncoding');
$writer = $this->startDocument($encoding);
$writer->startElement($root['name']);
// Create the wrapping element with no namespaces if no namespaces were present
if (!empty($root['namespaces'])) {
// Create the wrapping element with an array of one or more namespaces
foreach ((array) $root['namespaces'] as $prefix => $uri) {
$nsLabel = 'xmlns';
if (!is_numeric($prefix)) {
$nsLabel .= ':'.$prefix;
}
$writer->writeAttribute($nsLabel, $uri);
}
}
return $writer;
}
/**
* Recursively build the XML body
*
* @param \XMLWriter $writer XML to modify
* @param Parameter $param API Parameter
* @param mixed $value Value to add
*/
protected function addXml(\XMLWriter $writer, Parameter $param, $value)
{
$value = $param->filter($value);
$type = $param->getType();
$name = $param->getWireName();
$prefix = null;
$namespace = $param->getData('xmlNamespace');
if (false !== strpos($name, ':')) {
list($prefix, $name) = explode(':', $name, 2);
}
if ($type == 'object' || $type == 'array') {
if (!$param->getData('xmlFlattened')) {
if ($namespace) {
$writer->startElementNS(null, $name, $namespace);
} else {
$writer->startElement($name);
}
}
if ($param->getType() == 'array') {
$this->addXmlArray($writer, $param, $value);
} elseif ($param->getType() == 'object') {
$this->addXmlObject($writer, $param, $value);
}
if (!$param->getData('xmlFlattened')) {
$writer->endElement();
}
return;
}
if ($param->getData('xmlAttribute')) {
$this->writeAttribute($writer, $prefix, $name, $namespace, $value);
} else {
$this->writeElement($writer, $prefix, $name, $namespace, $value);
}
}
/**
* Write an attribute with namespace if used
*
* @param \XMLWriter $writer XMLWriter instance
* @param string $prefix Namespace prefix if any
* @param string $name Attribute name
* @param string $namespace The uri of the namespace
* @param string $value The attribute content
*/
protected function writeAttribute($writer, $prefix, $name, $namespace, $value)
{
if ($namespace) {
$writer->writeAttributeNS($prefix, $name, $namespace, $value);
} else {
$writer->writeAttribute($name, $value);
}
}
/**
* Write an element with namespace if used
*
* @param \XMLWriter $writer XML writer resource
* @param string $prefix Namespace prefix if any
* @param string $name Element name
* @param string $namespace The uri of the namespace
* @param string $value The element content
*/
protected function writeElement(\XMLWriter $writer, $prefix, $name, $namespace, $value)
{
if ($namespace) {
$writer->startElementNS($prefix, $name, $namespace);
} else {
$writer->startElement($name);
}
if (strpbrk($value, '<>&')) {
$writer->writeCData($value);
} else {
$writer->writeRaw($value);
}
$writer->endElement();
}
/**
* Create a new xml writer and start a document
*
* @param string $encoding document encoding
*
* @return \XMLWriter the writer resource
*
* @throws \RuntimeException if the document cannot be started
*/
protected function startDocument($encoding)
{
$this->writer = new \XMLWriter();
if (!$this->writer->openMemory()) {
throw new \RuntimeException('Unable to open XML document in memory');
}
if (!$this->writer->startDocument('1.0', $encoding)) {
throw new \RuntimeException('Unable to start XML document');
}
return $this->writer;
}
/**
* End the document and return the output
*
* @param \XMLWriter $writer
*
* @return string the writer resource
*/
protected function finishDocument($writer)
{
$writer->endDocument();
return $writer->outputMemory();
}
/**
* Add an array to the XML
*/
protected function addXmlArray(\XMLWriter $writer, Parameter $param, &$value)
{
if ($items = $param->getItems()) {
foreach ($value as $v) {
$this->addXml($writer, $items, $v);
}
}
}
/**
* Add an object to the XML
*/
protected function addXmlObject(\XMLWriter $writer, Parameter $param, &$value)
{
$noAttributes = [];
// add values which have attributes
foreach ($value as $name => $v) {
if ($property = $param->getProperty($name)) {
if ($property->getData('xmlAttribute')) {
$this->addXml($writer, $property, $v);
} else {
$noAttributes[] = ['value' => $v, 'property' => $property];
}
}
}
// now add values with no attributes
foreach ($noAttributes as $element) {
$this->addXml($writer, $element['property'], $element['value']);
}
}
private function visitWithValue(
$value,
Parameter $param,
Operation $operation
) {
if (!$this->writer) {
$this->createRootElement($operation);
}
$this->addXml($this->writer, $param, $value);
}
}