2018-01-28 12:17:19 -05:00
|
|
|
<?php
|
2021-09-13 14:51:12 -04:00
|
|
|
|
2018-01-28 12:17:19 -05:00
|
|
|
/**
|
|
|
|
* The MIT License
|
|
|
|
* Copyright (c) 2007 Andy Smith
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
2018-01-28 12:17:19 -05:00
|
|
|
namespace Abraham\TwitterOAuth;
|
|
|
|
|
|
|
|
class Request
|
|
|
|
{
|
|
|
|
protected $parameters;
|
|
|
|
protected $httpMethod;
|
|
|
|
protected $httpUrl;
|
2021-09-13 14:51:12 -04:00
|
|
|
protected $json;
|
2018-01-28 12:17:19 -05:00
|
|
|
public static $version = '1.0';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* @param string $httpMethod
|
|
|
|
* @param string $httpUrl
|
|
|
|
* @param array|null $parameters
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function __construct(
|
|
|
|
string $httpMethod,
|
|
|
|
string $httpUrl,
|
|
|
|
?array $parameters = []
|
|
|
|
) {
|
|
|
|
$parameters = array_merge(
|
|
|
|
Util::parseParameters(parse_url($httpUrl, PHP_URL_QUERY)),
|
|
|
|
$parameters
|
|
|
|
);
|
2018-01-28 12:17:19 -05:00
|
|
|
$this->parameters = $parameters;
|
|
|
|
$this->httpMethod = $httpMethod;
|
|
|
|
$this->httpUrl = $httpUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* pretty much a helper function to set up the request
|
|
|
|
*
|
|
|
|
* @param Consumer $consumer
|
|
|
|
* @param Token $token
|
|
|
|
* @param string $httpMethod
|
|
|
|
* @param string $httpUrl
|
|
|
|
* @param array $parameters
|
|
|
|
*
|
|
|
|
* @return Request
|
|
|
|
*/
|
|
|
|
public static function fromConsumerAndToken(
|
|
|
|
Consumer $consumer,
|
|
|
|
Token $token = null,
|
2021-09-13 14:51:12 -04:00
|
|
|
string $httpMethod,
|
|
|
|
string $httpUrl,
|
|
|
|
array $parameters = [],
|
|
|
|
$json = false
|
2018-01-28 12:17:19 -05:00
|
|
|
) {
|
|
|
|
$defaults = [
|
2021-09-13 14:51:12 -04:00
|
|
|
'oauth_version' => Request::$version,
|
|
|
|
'oauth_nonce' => Request::generateNonce(),
|
|
|
|
'oauth_timestamp' => time(),
|
|
|
|
'oauth_consumer_key' => $consumer->key,
|
2018-01-28 12:17:19 -05:00
|
|
|
];
|
|
|
|
if (null !== $token) {
|
|
|
|
$defaults['oauth_token'] = $token->key;
|
|
|
|
}
|
|
|
|
|
2021-09-13 14:51:12 -04:00
|
|
|
// The json payload is not included in the signature on json requests,
|
|
|
|
// therefore it shouldn't be included in the parameters array.
|
|
|
|
if ($json) {
|
|
|
|
$parameters = $defaults;
|
|
|
|
} else {
|
|
|
|
$parameters = array_merge($defaults, $parameters);
|
|
|
|
}
|
2018-01-28 12:17:19 -05:00
|
|
|
|
|
|
|
return new Request($httpMethod, $httpUrl, $parameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $name
|
|
|
|
* @param string $value
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function setParameter(string $name, string $value)
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
$this->parameters[$name] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-09-13 14:51:12 -04:00
|
|
|
* @param string $name
|
2018-01-28 12:17:19 -05:00
|
|
|
*
|
|
|
|
* @return string|null
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function getParameter(string $name): ?string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
2021-09-13 14:51:12 -04:00
|
|
|
return isset($this->parameters[$name])
|
|
|
|
? $this->parameters[$name]
|
|
|
|
: null;
|
2018-01-28 12:17:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function getParameters(): array
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
return $this->parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-09-13 14:51:12 -04:00
|
|
|
* @param string $name
|
2018-01-28 12:17:19 -05:00
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function removeParameter(string $name): void
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
unset($this->parameters[$name]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The request parameters, sorted and concatenated into a normalized string.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function getSignableParameters(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
// Grab all parameters
|
|
|
|
$params = $this->parameters;
|
|
|
|
|
|
|
|
// Remove oauth_signature if present
|
|
|
|
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
|
|
|
|
if (isset($params['oauth_signature'])) {
|
|
|
|
unset($params['oauth_signature']);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Util::buildHttpQuery($params);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the base string of this request
|
|
|
|
*
|
|
|
|
* The base string defined as the method, the url
|
|
|
|
* and the parameters (normalized), each urlencoded
|
|
|
|
* and the concated with &.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function getSignatureBaseString(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
$parts = [
|
|
|
|
$this->getNormalizedHttpMethod(),
|
|
|
|
$this->getNormalizedHttpUrl(),
|
2021-09-13 14:51:12 -04:00
|
|
|
$this->getSignableParameters(),
|
2018-01-28 12:17:19 -05:00
|
|
|
];
|
|
|
|
|
|
|
|
$parts = Util::urlencodeRfc3986($parts);
|
|
|
|
|
|
|
|
return implode('&', $parts);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the HTTP Method in uppercase
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function getNormalizedHttpMethod(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
return strtoupper($this->httpMethod);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* parses the url and rebuilds it to be
|
|
|
|
* scheme://host/path
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function getNormalizedHttpUrl(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
$parts = parse_url($this->httpUrl);
|
|
|
|
|
|
|
|
$scheme = $parts['scheme'];
|
|
|
|
$host = strtolower($parts['host']);
|
|
|
|
$path = $parts['path'];
|
|
|
|
|
|
|
|
return "$scheme://$host$path";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Builds a url usable for a GET request
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function toUrl(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
$postData = $this->toPostdata();
|
|
|
|
$out = $this->getNormalizedHttpUrl();
|
|
|
|
if ($postData) {
|
|
|
|
$out .= '?' . $postData;
|
|
|
|
}
|
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Builds the data one would send in a POST request
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function toPostdata(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
return Util::buildHttpQuery($this->parameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Builds the Authorization: header
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
* @throws TwitterOAuthException
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function toHeader(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
$first = true;
|
|
|
|
$out = 'Authorization: OAuth';
|
|
|
|
foreach ($this->parameters as $k => $v) {
|
2021-09-13 14:51:12 -04:00
|
|
|
if (substr($k, 0, 5) != 'oauth') {
|
2018-01-28 12:17:19 -05:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (is_array($v)) {
|
2021-09-13 14:51:12 -04:00
|
|
|
throw new TwitterOAuthException(
|
|
|
|
'Arrays not supported in headers'
|
|
|
|
);
|
2018-01-28 12:17:19 -05:00
|
|
|
}
|
2021-09-13 14:51:12 -04:00
|
|
|
$out .= $first ? ' ' : ', ';
|
|
|
|
$out .=
|
|
|
|
Util::urlencodeRfc3986($k) .
|
|
|
|
'="' .
|
|
|
|
Util::urlencodeRfc3986($v) .
|
|
|
|
'"';
|
2018-01-28 12:17:19 -05:00
|
|
|
$first = false;
|
|
|
|
}
|
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function __toString(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
return $this->toUrl();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param SignatureMethod $signatureMethod
|
|
|
|
* @param Consumer $consumer
|
|
|
|
* @param Token $token
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function signRequest(
|
|
|
|
SignatureMethod $signatureMethod,
|
|
|
|
Consumer $consumer,
|
|
|
|
Token $token = null
|
|
|
|
) {
|
|
|
|
$this->setParameter(
|
|
|
|
'oauth_signature_method',
|
|
|
|
$signatureMethod->getName()
|
|
|
|
);
|
2018-01-28 12:17:19 -05:00
|
|
|
$signature = $this->buildSignature($signatureMethod, $consumer, $token);
|
2021-09-13 14:51:12 -04:00
|
|
|
$this->setParameter('oauth_signature', $signature);
|
2018-01-28 12:17:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param SignatureMethod $signatureMethod
|
|
|
|
* @param Consumer $consumer
|
|
|
|
* @param Token $token
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public function buildSignature(
|
|
|
|
SignatureMethod $signatureMethod,
|
|
|
|
Consumer $consumer,
|
|
|
|
Token $token = null
|
|
|
|
): string {
|
2018-01-28 12:17:19 -05:00
|
|
|
return $signatureMethod->buildSignature($this, $consumer, $token);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-09-13 14:51:12 -04:00
|
|
|
public static function generateNonce(): string
|
2018-01-28 12:17:19 -05:00
|
|
|
{
|
|
|
|
return md5(microtime() . mt_rand());
|
|
|
|
}
|
|
|
|
}
|