Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Tests

on:
push:
branches:
- 'master'
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
phpunit:
# GitHub-hosted runner: this repository is public, so pull requests from forks
# must not run on self-hosted runners.
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['8.3', '8.4', '8.5']
dependencies: ['highest']
include:
# Lowest supported PHP with the lowest allowed dependencies
- php: '8.1'
dependencies: 'lowest'
name: PHP ${{ matrix.php }} (${{ matrix.dependencies }})
steps:
- uses: actions/checkout@v4

- name: Set PHP version
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring, intl
coverage: none

- name: Composer Install
run: |
if [ "${{ matrix.dependencies }}" = "lowest" ]; then
composer update -n --prefer-dist --no-scripts --prefer-lowest --prefer-stable
else
composer update -n --prefer-dist --no-scripts
fi

- name: Run PHPUnit
run: ./vendor/bin/phpunit
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ vendor/
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
.phpunit.cache/
.phpunit.result.cache
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
You can sign up for the API [here](https://www.pdffiller.com/en/developers#tab-pricing)

## System Requirements
* PHP >= 7.0 but the latest stable version of PHP is recommended;
* PHP >= 8.1 (tested on PHP 8.1–8.5);
* `mbstring` extension;
* `intl` extension;

Expand Down
17 changes: 12 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,35 @@
}
],
"require": {
"php": ">=7.0",
"league/oauth2-client": "^2.6",
"php": ">=8.1",
"league/oauth2-client": "^2.8",
"oodle/inflect": "^0.2.0",
"guzzlehttp/guzzle": "^7.4"
},
"require-dev": {
"adammbalogh/key-value-store-file": "^0.5.3",
"larapack/dd": "^1.0",
"nesbot/carbon": "^2.31",
"vlucas/phpdotenv": "^3.3|^5.4"
"nesbot/carbon": "^2.31 || ^3.0",
"vlucas/phpdotenv": "^3.3|^5.4",
"phpunit/phpunit": "^10.5 || ^11.5 || ^12.5 || ^13.0"
},
"autoload": {
"psr-4": {
"PDFfiller\\OAuth2\\Client\\Provider\\": "src/"
}
},
"autoload-dev": {
"psr-4": { "Examples\\": "examples/" }
"psr-4": {
"Examples\\": "examples/",
"PDFfiller\\OAuth2\\Client\\Provider\\Tests\\": "tests/"
}
},
"config": {
"allow-plugins": {
"kylekatarnls/update-helper": false
}
},
"scripts": {
"test": "phpunit"
}
}
19 changes: 19 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="vendor/autoload.php"
colors="true"
failOnWarning="true"
failOnNotice="true"
failOnDeprecation="true">
<testsuites>
<testsuite name="unit">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>

<source>
<include>
<directory suffix=".php">src</directory>
</include>
</source>
</phpunit>
1 change: 1 addition & 0 deletions src/Core/AbstractObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*
* @package PDFfiller\OAuth2\Client\Provider\Core
*/
#[\AllowDynamicProperties]
abstract class AbstractObject implements Arrayable
{
use CastsTrait;
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Exception extends \Exception
* @param int $code
* @param Exception|null $previous
*/
public function __construct(string $message = "", $code = 0, Exception $previous = null)
public function __construct(string $message = "", $code = 0, ?Exception $previous = null)
{
if (empty($message)) {
$message = $this->getDefaultMessage();
Expand Down
8 changes: 8 additions & 0 deletions src/Core/ListObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public function offsetExists($offset): bool
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
if (isset($this->items[$offset])) {
Expand All @@ -61,6 +62,7 @@ public function offsetGet($offset)
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
Expand All @@ -73,6 +75,7 @@ public function offsetSet($offset, $value)
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->items[$offset]);
Expand All @@ -81,6 +84,7 @@ public function offsetUnset($offset)
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function current()
{
return current($this->items);
Expand All @@ -89,6 +93,7 @@ public function current()
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function next()
{
return next($this->items);
Expand All @@ -97,6 +102,7 @@ public function next()
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function key()
{
return key($this->items);
Expand All @@ -105,6 +111,7 @@ public function key()
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function valid()
{
return key($this->items) !== null;
Expand All @@ -113,6 +120,7 @@ public function valid()
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function rewind()
{
return reset($this->items);
Expand Down
5 changes: 4 additions & 1 deletion src/DTO/FillableFieldsList.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private function getFields()
/**
* @inheritdoc
*/
public function offsetExists($offset)
public function offsetExists($offset): bool
{
$fields = $this->getFields();

Expand All @@ -71,6 +71,7 @@ public function offsetExists($offset)
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
$fields = array_flip($this->getFields());
Expand All @@ -87,6 +88,7 @@ public function offsetGet($offset)
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
if ($value instanceof FillableField) {
Expand Down Expand Up @@ -122,6 +124,7 @@ public function offsetSet($offset, $value)
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function offsetUnset($offset)
{
$fields = array_flip($this->getFields());
Expand Down
2 changes: 1 addition & 1 deletion src/Exceptions/ErrorsException.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ErrorsException extends Exception
* @param int $code
* @param Exception|null $previous
*/
public function __construct($errors, $message = "", $code = 0, Exception $previous = null)
public function __construct($errors, $message = "", $code = 0, ?Exception $previous = null)
{
$this->errors = $errors;
parent::__construct($message, $code, $previous);
Expand Down
2 changes: 1 addition & 1 deletion src/Exceptions/OptionsMissingException.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class OptionsMissingException extends Exception
* @param int $code
* @param Exception|null $previous
*/
public function __construct($options, $code = 0, Exception $previous = null)
public function __construct($options, $code = 0, ?Exception $previous = null)
{
$this->options = $options;
parent::__construct("", $code, $previous);
Expand Down
2 changes: 1 addition & 1 deletion src/Exceptions/TypeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class TypeException extends Exception
* @param int $code
* @param Exception|null $previous
*/
public function __construct($types = [], $message = "", $code = 0, Exception $previous = null)
public function __construct($types = [], $message = "", $code = 0, ?Exception $previous = null)
{
$this->typesAllowed = $types;
parent::__construct($message, $code, $previous);
Expand Down
55 changes: 48 additions & 7 deletions src/PDFfiller.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
use PDFfiller\OAuth2\Client\Provider\Exceptions\InvalidBodyException;
use PDFfiller\OAuth2\Client\Provider\Exceptions\InvalidBodySourceException;
use PDFfiller\OAuth2\Client\Provider\Exceptions\InvalidQueryException;
use PDFfiller\OAuth2\Client\Provider\Exceptions\InvalidRequestException;
use PDFfiller\OAuth2\Client\Provider\Exceptions\OptionsMissingException;
use PDFfiller\OAuth2\Client\Provider\Exceptions\ResponseException;
use PDFfiller\OAuth2\Client\Provider\Exceptions\TokenMissingException;
use League\OAuth2\Client\Provider\GenericProvider;
use GuzzleHttp\Exception\BadResponseException;
use Psr\Http\Message\RequestInterface;
use \GuzzleHttp\Psr7 as Psr7;
use Psr\Http\Message\ResponseInterface;
Expand Down Expand Up @@ -64,12 +66,21 @@ public function __construct(array $options = [], array $collaborators = [])
* @param AccessToken|string $token
* @param array $options
* @return RequestInterface
* @throws InvalidRequestException if the URL leaves urlApiDomain
*/
public function getAuthenticatedRequest($method, $url, $token, array $options = [])
{
$baseUri = new Psr7\Uri($this->urlApiDomain);
$relativeUri = new Psr7\Uri($url);
$newUri = Psr7\Uri::resolve($baseUri, $relativeUri);
$newUri = Psr7\UriResolver::resolve($baseUri, $relativeUri);

// Never send the access token outside of urlApiDomain
if ($newUri->getScheme() !== $baseUri->getScheme()
|| strtolower($newUri->getHost()) !== strtolower($baseUri->getHost())
|| $newUri->getPort() !== $baseUri->getPort()
) {
throw new InvalidRequestException('The request URL must use the scheme, host and port of urlApiDomain.');
}

return parent::getAuthenticatedRequest($method, $newUri, $token, $options);
}
Expand All @@ -91,7 +102,7 @@ private function applyOptions(RequestInterface $request, array &$options)
if (isset($options['multipart'])) {
throw new InvalidBodySourceException();
}
$options['body'] = http_build_query($options['form_params'], null, '&');
$options['body'] = http_build_query($options['form_params'], '', '&');
unset($options['form_params']);
$options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
}
Expand Down Expand Up @@ -121,7 +132,7 @@ private function applyOptions(RequestInterface $request, array &$options)
if (is_array($options['body'])) {
throw new InvalidBodyException();
}
$modify['body'] = Psr7\stream_for($options['body']);
$modify['body'] = Psr7\Utils::streamFor($options['body']);
unset($options['body']);
}

Expand All @@ -147,7 +158,7 @@ private function applyOptions(RequestInterface $request, array &$options)
if (isset($options['query'])) {
$value = $options['query'];
if (is_array($value)) {
$value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);
$value = http_build_query($value, '', '&', PHP_QUERY_RFC3986);
}
if (!is_string($value)) {
throw new InvalidQueryException();
Expand All @@ -157,12 +168,12 @@ private function applyOptions(RequestInterface $request, array &$options)
}

if (isset($options['json'])) {
$modify['body'] = Psr7\stream_for(json_encode($options['json']));
$modify['body'] = Psr7\Utils::streamFor(json_encode($options['json']));
$options['_conditional']['Content-Type'] = 'application/json';
unset($options['json']);
}

$request = Psr7\modify_request($request, $modify);
$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.
Expand All @@ -179,7 +190,7 @@ private function applyOptions(RequestInterface $request, array &$options)
$modify['set_headers'][$k] = $v;
}
}
$request = Psr7\modify_request($request, $modify);
$request = Psr7\Utils::modifyRequest($request, $modify);
// Don't pass this internal value along to middleware/handlers.
unset($options['_conditional']);
}
Expand Down Expand Up @@ -259,6 +270,36 @@ public function getStatusCode()
return $this->statusCode;
}

/**
* Sends a request and returns the response. A 4xx/5xx response is returned,
* not thrown, so that checkResponse() can handle it (as in league/oauth2-client 1.x).
*
* @param RequestInterface $request
* @return ResponseInterface
*/
protected function sendRequest(RequestInterface $request)
{
try {
return $this->getHttpClient()->send($request);
} catch (BadResponseException $e) {
return $e->getResponse();
}
}

/**
* Sends a request and returns the parsed response.
*
* league/oauth2-client 2.x expects getResponse() to return a ResponseInterface
* here; our getResponse() already parses and checks it.
*
* @param RequestInterface $request
* @return array
*/
public function getParsedResponse(RequestInterface $request)
{
return $this->getResponse($request);
}

/**
* @inheritdoc
*/
Expand Down
Loading
Loading