Skip to content

Commit

Permalink
Merge pull request #672 from DannyvdSluijs/add-phpstan
Browse files Browse the repository at this point in the history
Add PHPStan
  • Loading branch information
stephangroen authored Feb 27, 2025
2 parents 05412be + 2952983 commit caeb3d7
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 41 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Run static analysis

on: [pull_request]

jobs:
static-analysis:
name: Static analysis
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.4

- name: Composer install
run: composer install --prefer-dist --no-interaction --no-progress --no-suggest

- name: Run static analysis
run: vendor/bin/phpstan
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"ext-json": "*"
},
"require-dev": {
"phpstan/phpstan": "^2.1",
"phpunit/phpunit": "^9.6"
},
"autoload": {
Expand Down
27 changes: 12 additions & 15 deletions example/example.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,28 @@
*
* @param string $key
*
* @return null|string
* @return null|string|int
*/
function getValue($key)
function getValue(string $key)
{
$storage = json_decode(file_get_contents('storage.json'), true);
$storage = json_decode(file_get_contents('storage.json'), true, 512, JSON_THROW_ON_ERROR);
if (array_key_exists($key, $storage)) {
return $storage[$key];
}

return null;
}

/**
* Function to persist some data for the example.
*
* @param string $key
* @param string $value
* @param string|int $value
*/
function setValue($key, $value)
function setValue(string $key, $value)
{
$storage = json_decode(file_get_contents('storage.json'), true);
$storage = json_decode(file_get_contents('storage.json'), true, 512, JSON_THROW_ON_ERROR);
$storage[$key] = $value;
file_put_contents('storage.json', json_encode($storage));
file_put_contents('storage.json', json_encode($storage, JSON_THROW_ON_ERROR));
}

/**
Expand All @@ -46,10 +47,8 @@ function authorize()

/**
* Callback function that sets values that expire and are refreshed by Connection.
*
* @param \Picqer\Financials\Exact\Connection $connection
*/
function tokenUpdateCallback(\Picqer\Financials\Exact\Connection $connection)
function tokenUpdateCallback(\Picqer\Financials\Exact\Connection $connection): void
{
// Save the new tokens for next connections
setValue('accesstoken', $connection->getAccessToken());
Expand All @@ -63,10 +62,8 @@ function tokenUpdateCallback(\Picqer\Financials\Exact\Connection $connection)
* Function to connect to Exact, this creates the client and automatically retrieves oAuth tokens if needed.
*
* @throws Exception
*
* @return \Picqer\Financials\Exact\Connection
*/
function connect()
function connect(): \Picqer\Financials\Exact\Connection
{
$connection = new \Picqer\Financials\Exact\Connection();
$connection->setRedirectUrl('__REDIRECT_URL__');
Expand Down Expand Up @@ -111,7 +108,7 @@ function connect()
setValue('authorizationcode', $_GET['code']);
}

// If we do not have a authorization code, authorize first to setup tokens
// If we do not have an authorization code, authorize first to set up tokens
if (getValue('authorizationcode') === null) {
authorize();
}
Expand Down
181 changes: 181 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
parameters:
ignoreErrors:
-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\AssemblyOrder\:\:\$PartItems contains unknown class Picqer\\Financials\\Exact\\PartItem\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/AssemblyOrder.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\BulkGoodsDelivery\:\:\$GoodsDeliveryLines contains unknown class Picqer\\Financials\\Exact\\goodsdeliverylines\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/BulkGoodsDelivery.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\BulkGoodsDeliveryLine\:\:\$BatchNumbers contains unknown class Picqer\\Financials\\Exact\\stockbatchnumbers\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/BulkGoodsDeliveryLine.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\BulkGoodsDeliveryLine\:\:\$SerialNumbers contains unknown class Picqer\\Financials\\Exact\\stockserialnumbers\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/BulkGoodsDeliveryLine.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\DigitalOrderPickingLine\:\:\$PickingLocations contains unknown class Picqer\\Financials\\Exact\\PickingLocation\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/DigitalOrderPickingLine.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\Division\:\:\$Class_01 contains unknown class Picqer\\Financials\\Exact\\divisionclasses\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/Division.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\Division\:\:\$Class_02 contains unknown class Picqer\\Financials\\Exact\\divisionclasses\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/Division.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\Division\:\:\$Class_03 contains unknown class Picqer\\Financials\\Exact\\divisionclasses\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/Division.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\Division\:\:\$Class_04 contains unknown class Picqer\\Financials\\Exact\\divisionclasses\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/Division.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\Division\:\:\$Class_05 contains unknown class Picqer\\Financials\\Exact\\divisionclasses\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/Division.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\Division\:\:\$HID contains unknown class Picqer\\Financials\\Exact\\int64\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/Division.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\ItemAssortment\:\:\$Properties contains unknown class Picqer\\Financials\\Exact\\Property\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/ItemAssortment.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\LogisticsReasonsCodes\:\:\$Types contains unknown class Picqer\\Financials\\Exact\\Type\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/LogisticsReasonsCodes.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\PayablesList\:\:\$Notes contains unknown class Picqer\\Financials\\Exact\\Note\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/PayablesList.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\PayablesListByAccount\:\:\$Notes contains unknown class Picqer\\Financials\\Exact\\Note\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/PayablesListByAccount.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\PayablesListByAccountAndAgeGroup\:\:\$Notes contains unknown class Picqer\\Financials\\Exact\\Note\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/PayablesListByAccountAndAgeGroup.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\PayablesListByAgeGroup\:\:\$Notes contains unknown class Picqer\\Financials\\Exact\\Note\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/PayablesListByAgeGroup.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\ProcessPayment\:\:\$PaymentIDs contains unknown class Picqer\\Financials\\Exact\\PaymentID\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/ProcessPayment.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\Project\:\:\$BudgetedHoursPerHourType contains unknown class Picqer\\Financials\\Exact\\BudgetedHoursPerHourType\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/Project.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\ReasonForLogistic\:\:\$Types contains unknown class Picqer\\Financials\\Exact\\Type\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/ReasonForLogistic.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\ReceivablesList\:\:\$Notes contains unknown class Picqer\\Financials\\Exact\\Note\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/ReceivablesList.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\ReceivablesListByAccount\:\:\$Notes contains unknown class Picqer\\Financials\\Exact\\Note\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/ReceivablesListByAccount.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\ReceivablesListByAccountAndAgeGroup\:\:\$Notes contains unknown class Picqer\\Financials\\Exact\\Note\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/ReceivablesListByAccountAndAgeGroup.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\ReceivablesListByAgeGroup\:\:\$Notes contains unknown class Picqer\\Financials\\Exact\\Note\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/ReceivablesListByAgeGroup.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\Schedule\:\:\$ScheduleEntries contains unknown class Picqer\\Financials\\Exact\\ScheduleEntry\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/Schedule.php

-
message: '#^Class Picqer\\Financials\\Exact\\SalesOrderLine referenced with incorrect case\: Picqer\\Financials\\Exact\\SalesOrderline\.$#'
identifier: class.nameCase
count: 1
path: src/Picqer/Financials/Exact/ShopOrder.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\ShopOrderRoutingStepPlan\:\:\$TimeTransactions contains unknown class Picqer\\Financials\\Exact\\TimeTransaction\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/ShopOrderRoutingStepPlan.php

-
message: '#^PHPDoc tag @property for property Picqer\\Financials\\Exact\\User\:\:\$UserRoles contains unknown class Picqer\\Financials\\Exact\\UserRoles\.$#'
identifier: class.notFound
count: 1
path: src/Picqer/Financials/Exact/User.php

-
message: '#^Class Picqer\\Financials\\Exact\\VatPercentage referenced with incorrect case\: Picqer\\Financials\\Exact\\VATPercentage\.$#'
identifier: class.nameCase
count: 1
path: src/Picqer/Financials/Exact/VatCode.php

-
message: '#^Trait Picqer\\Financials\\Exact\\Webhook\\Authenticatable is used zero times and is not analysed\.$#'
identifier: trait.unused
count: 1
path: src/Picqer/Financials/Exact/Webhook/Authenticatable.php
12 changes: 12 additions & 0 deletions phpstan.dist.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
includes:
- phpstan-baseline.neon

parameters:
level: 5
paths:
- example
- src
- tests
phpVersion:
min: 70400
max: 80317
29 changes: 11 additions & 18 deletions src/Picqer/Financials/Exact/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;

/**
* Class Connection.
Expand Down Expand Up @@ -72,29 +72,29 @@ class Connection
private ?Client $client = null;

/**
* @var callable(Connection)
* @var callable(Connection): void|null
*/
private $tokenUpdateCallback;

/**
* @var callable(Connection)
* @var callable(Connection): void|null
*/
private $acquireAccessTokenLockCallback;

/**
* @var callable(Connection)
* @var callable(Connection): void|null
*/
private $acquireAccessTokenUnlockCallback;

/**
* @var callable(Connection)
* @var callable(Connection): void|null
*/
private $refreshAccessTokenCallback;

/**
* @var callable[]
* @var list<callable(callable): callable>
*/
protected $middleWares = [];
protected array $middleWares = [];

public ?string $nextUrl = null;

Expand Down Expand Up @@ -439,14 +439,11 @@ public function needsAuthentication(): bool
}

/**
* @param Response $response
* @param bool $returnSingleIfPossible
*
* @throws ApiException
*
* @return mixed
*/
private function parseResponse(Response $response, $returnSingleIfPossible = true)
private function parseResponse(ResponseInterface $response, bool $returnSingleIfPossible = true)
{
try {
$this->extractRateLimits($response);
Expand Down Expand Up @@ -486,13 +483,11 @@ private function parseResponse(Response $response, $returnSingleIfPossible = tru
}

/**
* @param Response $response
*
* @throws ApiException
*
* @return mixed
*/
private function parseResponseXml(Response $response)
private function parseResponseXml(ResponseInterface $response)
{
try {
if ($response->getStatusCode() === 204) {
Expand All @@ -519,13 +514,11 @@ private function parseResponseXml(Response $response)
}

/**
* @param Response $response
*
* @throws ApiException
*
* @return mixed
*/
private function parseDownloadResponseXml(Response $response)
private function parseDownloadResponseXml(ResponseInterface $response)
{
try {
if ($response->getStatusCode() === 204) {
Expand Down Expand Up @@ -857,7 +850,7 @@ public function setTokenUrl(string $tokenUrl): void
$this->tokenUrl = $tokenUrl;
}

private function extractRateLimits(Response $response): void
private function extractRateLimits(ResponseInterface $response): void
{
$this->dailyLimit = (int) $response->getHeaderLine('X-RateLimit-Limit');
$this->dailyLimitRemaining = (int) $response->getHeaderLine('X-RateLimit-Remaining');
Expand Down
Loading

0 comments on commit caeb3d7

Please sign in to comment.