Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Developer tools #26

Merged
merged 2 commits into from
Apr 29, 2023
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
26 changes: 26 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: "Code check"

on:
workflow_call: null
pull_request: null
push:
branches:
- main

concurrency:
group: larastrict-check-${{ github.ref }}
cancel-in-progress: true

jobs:
code:
name: "Code check"
uses: wrk-flow/reusable-workflows/.github/workflows/php-check.yml@b0886c7fa81dab2fb2615c06eb66e94711652056
pionl marked this conversation as resolved.
Show resolved Hide resolved
secrets: inherit

tests:
name: "Run tests"
strategy:
matrix:
php-version: [ "7.4", "8.0", "8.1", "8.2" ]
uses: wrk-flow/reusable-workflows/.github/workflows/php-tests.yml@7b6e90f753beb05d979bf4ad39a009b353a7c6cc
secrets: inherit
23 changes: 20 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,29 @@
},
"minimum-stability": "stable",
"require": {
"php": ">=7.3",
"guzzlehttp/guzzle": ">=6.2",
"php": ">=7.4",
"guzzlehttp/guzzle": ">=7.5",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "9.5",
"vlucas/phpdotenv": "^2.4"
"vlucas/phpdotenv": "^2.4",
"phpstan/phpstan": "1.9.4",
"phpstan/phpstan-deprecation-rules": "^1.0.0",
"phpstan/phpstan-mockery": "^1.1.0",
"phpstan/phpstan-phpunit": "^1.1.1",
"rector/rector": "0.15.1",
"symplify/easy-coding-standard": "11.1.20"
},
"scripts": {
"check": ["Composer\\Config::disableProcessTimeout", "composer lint && composer test && composer lint:stan"],
"lint:check": "./vendor/bin/ecs",
"lint:fix": "./vendor/bin/ecs --fix",
"lint:stan": "./vendor/bin/phpstan",
"lint:upgrade:check": ["Composer\\Config::disableProcessTimeout","vendor/bin/rector process --dry-run"],
"lint:upgrade": ["Composer\\Config::disableProcessTimeout","vendor/bin/rector process"],
"lint": ["Composer\\Config::disableProcessTimeout","composer lint:upgrade && composer lint:fix && composer lint:stan"],
"test": "./vendor/bin/phpunit",
"test:coverage": "./vendor/bin/phpunit --coverage-text"
}
}
27 changes: 27 additions & 0 deletions ecs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

use PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer;
use Symplify\EasyCodingStandard\Config\ECSConfig;
use Symplify\EasyCodingStandard\ValueObject\Set\SetList;

return static function (ECSConfig $containerConfigurator): void {
$containerConfigurator->import(SetList::PSR_12);
$containerConfigurator->import(SetList::SYMPLIFY);
$containerConfigurator->import(SetList::COMMON);
$containerConfigurator->import(SetList::CLEAN_CODE);

$containerConfigurator->ruleWithConfiguration(ClassAttributesSeparationFixer::class, [
'elements' => [
'const' => 'only_if_meta',
'property' => 'one',
'method' => 'one',
],
]);

$containerConfigurator->parallel();
$containerConfigurator->paths(
[__DIR__ . '/src', __DIR__ . '/tests', __DIR__ . '/ecs.php', __DIR__ . '/rector.php']
);
};
23 changes: 23 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
- vendor/phpstan/phpstan-mockery/extension.neon

parameters:

parallel:
processTimeout: 600.0

paths:
- src
- tests

level: 5
pionl marked this conversation as resolved.
Show resolved Hide resolved

checkMissingIterableValueType: false

ignoreErrors:
-
message: '#^Unreachable statement - code above always terminates\.#'
path: '*/tests/*'
33 changes: 33 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

use Rector\CodingStyle\Rector\ClassConst\VarConstantCommentRector;
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersion;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Strict\Rector\AbstractFalsyScalarRuleFixerRector;
use Rector\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector;

return static function (RectorConfig $config): void {
$config->paths([__DIR__ . '/src', __DIR__ . '/tests']);
$config->phpVersion(PhpVersion::PHP_74);

// Define what rule sets will be applied
$config->import(LevelSetList::UP_TO_PHP_74);
$config->import(SetList::CODE_QUALITY);
$config->import(SetList::CODING_STYLE);
$config->importNames();
$config->importShortClasses(false);

$config->ruleWithConfiguration(
BooleanInBooleanNotRuleFixerRector::class,
[
AbstractFalsyScalarRuleFixerRector::TREAT_AS_NON_EMPTY => false,
]
);

$config->skip([VarConstantCommentRector::class, NewlineAfterStatementRector::class]);
};
35 changes: 11 additions & 24 deletions src/Api.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<?php

declare(strict_types=1);

namespace SmartEmailing\v3;

use GuzzleHttp\Client;
use SmartEmailing\v3\Request\Contactlists\ContactlistEndpoint;
use SmartEmailing\v3\Request\Credentials\Credentials;
use SmartEmailing\v3\Request\CustomFields\CustomFields;
use SmartEmailing\v3\Request\CustomRequest\CustomRequest;
use SmartEmailing\v3\Request\Email\EmailsEndpoint;
use SmartEmailing\v3\Request\Eshops\EshopOrders;
use SmartEmailing\v3\Request\Eshops\EshopOrdersBulk;
Expand All @@ -15,43 +18,32 @@
use SmartEmailing\v3\Request\Send\BulkCustomEmails;
use SmartEmailing\v3\Request\Send\BulkCustomSms;
use SmartEmailing\v3\Request\Send\TransactionalEmails;
use SmartEmailing\v3\Request\CustomRequest\CustomRequest;

/**
* Class Api
* @package SmartEmailing\v3
*
* @link https://app.smartemailing.cz/docs/api/v3/index.html#api-Tests-Aliveness_test
*/
class Api
{
/**
* The final API endpoint
* @var string
*/
private $apiUrl;
private string $apiUrl;

/** @var Client */
private $client;
private Client $client;

/**
* Api constructor.
*
* @param string $username
* @param string $apiKey
* @param string|null $apiUrl
*/
public function __construct(string $username, string $apiKey, $apiUrl = null)
public function __construct(string $username, string $apiKey, string $apiUrl = null)
{
$this->apiUrl = $apiUrl;
$this->apiUrl = $apiUrl ?? 'https://app.smartemailing.cz/api/v3/';
$this->client = new Client([
'auth' => [$username, $apiKey],
'base_uri' => ($apiUrl ? $apiUrl : 'https://app.smartemailing.cz/api/v3/')
'base_uri' => $this->apiUrl,
]);
}

/**
* Returns current API client with auth setup and base URL
* @return Client
*/
public function client(): Client
{
Expand All @@ -60,6 +52,7 @@ public function client(): Client

/**
* Creates new import request
*
* @return Import
*/
public function import()
Expand Down Expand Up @@ -91,9 +84,6 @@ public function newsletter(int $emailId, array $contactLists): Newsletter
return new Newsletter($this, $emailId, $contactLists);
}

/**
* @return Ping
*/
public function ping(): Ping
{
return new Ping($this);
Expand All @@ -104,9 +94,6 @@ public function customRequest(string $action, string $method = 'GET', array $pos
return new CustomRequest($this, $action, $method, $postData);
}

/**
* @return Credentials
*/
public function credentials(): Credentials
{
return new Credentials($this);
Expand All @@ -126,7 +113,7 @@ public function eshopOrdersBulk(): EshopOrdersBulk
{
return new EshopOrdersBulk($this);
}

public function customEmailsBulk(): BulkCustomEmails
{
return new BulkCustomEmails($this);
Expand Down
13 changes: 8 additions & 5 deletions src/Exceptions/InvalidFormatException.php
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
<?php

declare(strict_types=1);

namespace SmartEmailing\v3\Exceptions;

class InvalidFormatException extends \LogicException
{
/**
* Checks if the value is in the array. Throws exception if not
*
* @param mixed $value
* @param array $allowed
*/
public static function checkInArray($value, array $allowed)
{
if (!in_array($value, $allowed)) {
throw new InvalidFormatException("Value '{$value}' not allowed: ".implode(', ', $allowed));
if (in_array($value, $allowed, true) === false) {
throw new self(sprintf("Value '%s' not allowed: ", $value) . implode(', ', $allowed));
}
}

public static function checkAllowedValues(array $values, array $allowed)
{
$invalidFields = array_diff($values, $allowed);

if (count($invalidFields) > 0) {
throw new InvalidFormatException('These values are not allowed: '. implode(', ', $invalidFields));
if ($invalidFields !== []) {
throw new self('These values are not allowed: ' . implode(', ', $invalidFields));
}
}
}
21 changes: 8 additions & 13 deletions src/Exceptions/JsonDataInvalidException.php
Original file line number Diff line number Diff line change
@@ -1,36 +1,31 @@
<?php
namespace SmartEmailing\v3\Exceptions;

use Exception;
use stdClass;
declare(strict_types=1);

namespace SmartEmailing\v3\Exceptions;

class JsonDataInvalidException extends JsonDataMissingException
{
/**
* @inheritDoc
*/
public function __construct($key, $functionCheck, $code = 500, Exception $previous = null)
public function __construct($key, $functionCheck, $code = 500, \Exception $previous = null)
{
parent::__construct("The JSON value '{$key}' is invalid - {$functionCheck}", $code, $previous);
parent::__construct(sprintf("The JSON value '%s' is invalid - %s", $key, $functionCheck), $code, $previous);
}

/**
* Throws an exception if the key is not in the array
*
* @param array|stdClass $arrayOrObject
* @param array|\stdClass $arrayOrObject
* @param string $key
* @param string $functionCheck run a validation function)
*
* @return mixed the value
*
* @throws JsonDataMissingException
*/
public static function throwIfInValid($arrayOrObject, $key, $functionCheck)
{
$value = static::throwIfSet($arrayOrObject, $key);

if (!call_user_func($functionCheck, $value)) {
throw new JsonDataInvalidException($key, $functionCheck);
if (! call_user_func($functionCheck, $value)) {
throw new self($key, $functionCheck);
}

return $value;
Expand Down
25 changes: 10 additions & 15 deletions src/Exceptions/JsonDataMissingException.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
<?php
namespace SmartEmailing\v3\Exceptions;

use Exception;
declare(strict_types=1);

namespace SmartEmailing\v3\Exceptions;

class JsonDataMissingException extends Exception
class JsonDataMissingException extends \Exception
{
/**
* @inheritDoc
*/
public function __construct($key, $code = 500, Exception $previous = null)
public function __construct($key, $code = 500, \Exception $previous = null)
{
parent::__construct("The JSON response is missing '{$key}' value", $code, $previous);
parent::__construct(sprintf("The JSON response is missing '%s' value", $key), $code, $previous);
}

/**
Expand All @@ -20,24 +18,21 @@ public function __construct($key, $code = 500, Exception $previous = null)
* @param string $key
*
* @return mixed the value
*
* @throws JsonDataMissingException
*/
public static function throwIfSet($arrayOrObject, $key)
{
if (is_array($arrayOrObject)) {
if (!array_key_exists($key, $arrayOrObject)) {
throw new JsonDataMissingException($key);
if (array_key_exists($key, $arrayOrObject) === false) {
throw new self($key);
}

return $arrayOrObject[$key];
}

if (!property_exists($arrayOrObject, $key)) {
throw new JsonDataMissingException($key);
if (property_exists($arrayOrObject, $key) === false) {
throw new self($key);
}

return $arrayOrObject->{$key};
}

}
Loading