diff --git a/.docker/php7.3-dev/Dockerfile b/.docker/php-dev/Dockerfile
similarity index 53%
rename from .docker/php7.3-dev/Dockerfile
rename to .docker/php-dev/Dockerfile
index 3d5e25d..e594a2b 100644
--- a/.docker/php7.3-dev/Dockerfile
+++ b/.docker/php-dev/Dockerfile
@@ -1,16 +1,25 @@
-FROM php:7.3-cli
+FROM php:8.0-cli-alpine
-RUN apt-get update && apt-get install -y git unzip
+RUN apk update
+RUN apk add --no-cache bash
+RUN apk add --no-cache build-base
+RUN apk add --no-cache autoconf
+RUN apk add --no-cache automake
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_MEMORY_LIMIT -1
-RUN mkdir /.composer_cache
-ENV COMPOSER_CACHE_DIR /.composer_cache
-
-RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
-
# php extensions
+# intl
+RUN apk add --no-cache icu-dev
+RUN docker-php-ext-install intl
+RUN docker-php-ext-enable intl
+# xdebug
RUN pecl install xdebug
RUN docker-php-ext-enable xdebug
+
+RUN mkdir /.composer_cache
+ENV COMPOSER_CACHE_DIR /.composer_cache
+
+RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
diff --git a/.travis.yml b/.travis.yml
index 270a07b..2436a3e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,8 @@ language: php
matrix:
include:
- - php: 7.3
+ - php: 7.4
+ - php: 8.0
fast_finish: true
env:
diff --git a/Makefile b/Makefile
index 04a87a5..ea90b6c 100644
--- a/Makefile
+++ b/Makefile
@@ -38,19 +38,17 @@ composer: ## Execute composer command
phpunit: ## execute project unit tests
docker-compose run --rm --no-deps php sh -lc "./vendor/bin/phpunit $(conf)"
-.PHONY: style
-style: ## executes php analizers
+.PHONY: phpstan
+phpstan: ## executes phpstan analizer
docker-compose run --rm --no-deps php sh -lc './vendor/bin/phpstan analyse -l 6 -c phpstan.neon src tests'
+
+psalm: ## execute psalm analizer
docker-compose run --rm --no-deps php sh -lc './vendor/bin/psalm --config=psalm.xml'
.PHONY: lint
lint: ## checks syntax of PHP files
docker-compose run --rm --no-deps php sh -lc './vendor/bin/parallel-lint ./ --exclude vendor --exclude bin/.phpunit'
-.PHONY: layer
-layer: ## Check issues with layers (deptrac tool)
- docker-compose run --rm --no-deps php sh -lc './vendor/bin/deptrac analyze --formatter-graphviz=0'
-
.PHONY: logs
logs: ## look for service logs
docker-compose logs -f $(RUN_ARGS)
@@ -66,7 +64,7 @@ php-shell: ## PHP shell
unit-tests: ## Run unit-tests suite
docker-compose run --rm php sh -lc 'vendor/bin/phpunit --testsuite unit-tests'
-static-analysis: style layer coding-standards ## Run phpstan, easycoding standarts code static analysis
+static-analysis: psalm phpstan coding-standards ## Run phpstan, psalm, easycoding standarts code static analysis
coding-standards: ## Run check and validate code standards tests
docker-compose run --rm --no-deps php sh -lc 'vendor/bin/ecs check src tests'
@@ -78,5 +76,5 @@ coding-standards-fixer: ## Run code standards fixer
security-tests: ## The SensioLabs Security Checker
docker-compose run --rm --no-deps php sh -lc 'vendor/bin/security-checker security:check --end-point=http://security.sensiolabs.org/check_lock'
-.PHONY: test lint static-analysis phpunit coding-standards composer-validate
-test: build lint static-analysis phpunit coding-standards composer-validate stop ## Run all test suites
+.PHONY: test lint static-analysis coding-standards composer-validate phpunit
+test: build lint static-analysis coding-standards composer-validate phpunit stop ## Run all test suites
diff --git a/composer.json b/composer.json
index 48d7527..57b7c86 100644
--- a/composer.json
+++ b/composer.json
@@ -4,25 +4,26 @@
"description": "Micro module Base common library",
"license": "proprietary",
"require": {
- "php": "^7.3 || ^8.0",
+ "php": "^7.4 || ^8.0",
"ext-json": "*",
- "beberlei/assert": "^3.2",
+ "ext-intl": "*",
+ "beberlei/assert": "^3.3",
"psr/log": "^1.1",
"ramsey/uuid": "^3.8 || ^4.0",
"monolog/monolog": "~1.22 || ~2.0"
},
"require-dev": {
- "php-parallel-lint/php-console-highlighter": "^0.4",
- "php-parallel-lint/php-parallel-lint": "^1.0",
- "mockery/mockery": "^1.3",
- "phpmd/phpmd": "^2.8",
+ "php-parallel-lint/php-console-highlighter": "^0.5",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "mockery/mockery": "^1.4",
+ "phpmd/phpmd": "^2.9",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-mockery": "^0.12",
"phpstan/phpstan-phpunit": "^0.12",
- "phpunit/phpunit": "^9.4",
+ "phpunit/phpunit": "^9.3",
"roave/security-advisories": "dev-master",
- "symplify/easy-coding-standard": "^7.2",
- "vimeo/psalm": "^4.2"
+ "symplify/easy-coding-standard": "^9.0",
+ "vimeo/psalm": "^4.4"
},
"config": {
"preferred-install": {
diff --git a/docker-compose.yml b/docker-compose.yml
index f29c43f..17d5696 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,9 +3,10 @@ version: "3.7"
services:
php:
container_name: ${MICROBASE_COMPOSE_PROJECT_NAME}_php
- user: 1000:1000
build:
- context: .docker/php7.3-dev
+ context: .docker/php-dev
+ env_file:
+ - .env
volumes:
- ~/.composer/cache/:/.composer_cache/:rw
- .:/app:rw
diff --git a/ecs.php b/ecs.php
new file mode 100644
index 0000000..c9bc96a
--- /dev/null
+++ b/ecs.php
@@ -0,0 +1,15 @@
+import(__DIR__ . '/vendor/symplify/easy-coding-standard/config/set/clean-code.php');
+ $containerConfigurator->import(__DIR__ . '/vendor/symplify/easy-coding-standard/config/set/symfony.php');
+ $containerConfigurator->import(__DIR__ . '/vendor/symplify/easy-coding-standard/config/set/php71.php');
+ $containerConfigurator->import(__DIR__ . '/vendor/symplify/easy-coding-standard/config/set/psr12.php');
+ $parameters = $containerConfigurator->parameters();
+ $parameters->set('skip', [
+ ]);
+};
diff --git a/phpstan.neon b/phpstan.neon
index c1c0981..ca39598 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -3,5 +3,5 @@ includes:
parameters:
excludes_analyse:
- - src/Infrastructure/Testing/RedisInMemory.php
- - src/Infrastructure/Testing/RedisFactory.php
+ - tests/unit/Infrastructure/Repository/RedisInMemory.php
+ - tests/unit/Infrastructure/Factory/RedisFactory.php
diff --git a/psalm.xml b/psalm.xml
index 39b4cb3..51e3269 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -9,8 +9,8 @@
-
-
+
+
@@ -34,7 +34,6 @@
-
diff --git a/src/Domain/Adapter/HttpRequestInterface.php b/src/Domain/Adapter/HttpRequestInterface.php
new file mode 100644
index 0000000..be3e0c4
--- /dev/null
+++ b/src/Domain/Adapter/HttpRequestInterface.php
@@ -0,0 +1,32 @@
+
+ */
+ protected array $tags;
+
+ /**
+ * Global logging tags from application and environment.
+ *
+ * @var array
+ */
+ protected array $globalTags;
+
+ /**
+ * Additional tags.
+ *
+ * @var array
+ */
+ protected array $additionalTags;
+
+ /**
+ * CustomTagProcessor constructor.
+ *
+ * @param mixed[] $globalTags
+ * @param string[] $additionalTags
+ */
+ public function __construct(string $environment, string $release, array $globalTags = [], array $additionalTags = [])
+ {
+ $this->environment = $environment;
+ $this->release = $release;
+ $this->globalTags = $globalTags;
+ $this->additionalTags = $additionalTags;
+ }
+
+ /**
+ * Add custom tags to log tags. Method called by Monolog.
+ *
+ * @param mixed[] $record
+ *
+ * @return mixed[]
+ */
+ public function __invoke(array $record): array
+ {
+ $this->addAdditonalTags($record);
+ $this->addGlobalTags($record);
+ $record['extra']['tags'] = $this->tags;
+ $record['extra']['release'] = $this->release;
+ $record['extra']['environment'] = $this->environment;
+
+ return $record;
+ }
+
+ /**
+ * Add global tags, such exception level, version of php, application name etc.
+ *
+ * @param mixed[] $record
+ */
+ protected function addGlobalTags(array $record): void
+ {
+ $context = $record['context'];
+
+ if (isset($context['exception'])) {
+ $this->addTag('exception_type', $this->resolveExceptionLevelType($context['exception']));
+ }
+ $this->addTag('php_version', (string) phpversion());
+
+ foreach ($this->globalTags as $k => $v) {
+ $this->addTag($k, $v);
+ }
+ }
+
+ /**
+ * Add logging additional tags.
+ *
+ * @param mixed[] $record
+ */
+ protected function addAdditonalTags(array $record): void
+ {
+ $context = $record['context'];
+
+ foreach ($this->additionalTags as $key) {
+ if (isset($context[$key])) {
+ $this->addTag($key, $context[$key]);
+ }
+ }
+ }
+
+ /**
+ * Add logging tag.
+ *
+ * @param object|mixed[]|string|int $value
+ */
+ protected function addTag(string $key, $value): void
+ {
+ if (is_object($value)) {
+ $value = method_exists($value, 'normalize') ? json_encode($value->normalize()) : var_export($value, true);
+ }
+ $this->tags[$key] = $value;
+ }
+
+ /**
+ * Resolve exception level type based on exception.
+ */
+ protected function resolveExceptionLevelType(Throwable $e): string
+ {
+ switch (true) {
+ case $e instanceof AlertException:
+ return self::EXCEPTION_NAME_ALERT;
+
+ case $e instanceof CriticalException:
+ return self::EXCEPTION_NAME_CRITICAL;
+
+ case $e instanceof EmergencyException:
+ return self::EXCEPTION_NAME_EMERGENCY;
+
+ case $e instanceof RunTimeException:
+ return self::EXCEPTION_NAME_RUNTIME;
+
+ case $e instanceof TypeError:
+ return self::ERROR_NAME_TYPE;
+
+ case $e instanceof Error:
+ return self::ERROR_BASE_NAME;
+
+ default:
+ return self::EXCEPTION_NAME_DEFAULT;
+ }
+ }
+}
diff --git a/src/Utils/LoggerTrait.php b/src/Utils/LoggerTrait.php
index 81f0d06..6bc5bfb 100644
--- a/src/Utils/LoggerTrait.php
+++ b/src/Utils/LoggerTrait.php
@@ -40,8 +40,6 @@ trait LoggerTrait
/**
* ExceptionListener constructor.
*
- * @param LoggerInterface $logger
- *
* @return $this
*
* @required
@@ -56,8 +54,6 @@ public function setLogger(LoggerInterface $logger): self
/**
* Log an regular message or warning.
*
- * @param string $message
- * @param int $level
* @param mixed[] $context
*
* @return $this
@@ -91,7 +87,6 @@ public function logMessage(string $message, int $level, array $context = []): se
default:
throw new LoggerException(sprintf("Try to log invalid message level type '%s'", $level));
-
break;
}
@@ -102,7 +97,6 @@ public function logMessage(string $message, int $level, array $context = []): se
* Log an exception.
*
* @param Throwable $exception The \Throwable instance
- * @param int $level
* @param string $message The error message to log
*
* @return $this
@@ -140,7 +134,6 @@ public function logException(Throwable $exception, int $level, string $message):
default:
throw new LoggerException(sprintf("Try to log invalid error level type '%s'", $level));
-
break;
}
@@ -149,10 +142,6 @@ public function logException(Throwable $exception, int $level, string $message):
/**
* Define exception level from exception type.
- *
- * @param Throwable $exception
- *
- * @return int
*/
public function getExceptionLevel(Throwable $exception): int
{
@@ -175,10 +164,6 @@ public function getExceptionLevel(Throwable $exception): int
/**
* Generate exception message.
- *
- * @param Throwable $exception
- *
- * @return string
*/
public function getExceptionMessage(Throwable $exception): string
{
diff --git a/tests/unit/Infrastructure/Factory/RedisFactory.php b/tests/unit/Infrastructure/Factory/RedisFactory.php
new file mode 100644
index 0000000..b340a31
--- /dev/null
+++ b/tests/unit/Infrastructure/Factory/RedisFactory.php
@@ -0,0 +1,47 @@
+shouldReceive('get');
+ $redisGetMethod->andReturnUsing(
+ function ($key) {
+ return $key;
+ }
+ );
+ $redisSetMethod = $redis->shouldReceive('set');
+ $redisSetMethod->andReturnUsing(
+ function ($key, $value, $timeout = 0) {
+ return true;
+ }
+ );
+ $redisSaveMethod = $redis->shouldReceive('save');
+ $redisSaveMethod->andReturnUsing(
+ function () {
+ return true;
+ }
+ );
+
+ return $redis;
+ }
+}
diff --git a/tests/unit/Infrastructure/Repository/RedisInMemory.php b/tests/unit/Infrastructure/Repository/RedisInMemory.php
new file mode 100644
index 0000000..a55462d
--- /dev/null
+++ b/tests/unit/Infrastructure/Repository/RedisInMemory.php
@@ -0,0 +1,83 @@
+get('key');
+ */
+ public function get($key)
+ {
+ return $this->storage[$key] ?? false;
+ }
+
+ /**
+ * Set the string value in argument as value of the key.
+ *
+ * @param string $key
+ * @param string $value
+ * @param int|mixed[] $timeout [optional] Calling setex() is preferred if you want a timeout.
+ *
+ * @return bool TRUE if the command is successful
+ *
+ * @example $redis->set('key', 'value');
+ */
+ public function set($key, $value, $timeout = 0): bool
+ {
+ $this->storage[$key] = $value;
+
+ return true;
+ }
+
+ /**
+ * Performs a synchronous save.
+ *
+ * @return bool
+ *
+ * @example $redis->save();
+ */
+ public function save()
+ {
+ return true;
+ }
+}