diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8c80880 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +vendor/ +coverage diff --git a/.gitignore b/.gitignore index b5791de..76c5d31 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store .phpunit.result.cache -vendor/ \ No newline at end of file +vendor/ +coverage diff --git a/README.md b/README.md index 2bf59bf..cc163ba 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ - - - -

@@ -34,12 +30,10 @@ * [Installation](#installation) * [Configuration](#configuration) * [Usage](#usage) - * [Methods](#methods) + * [Methods](#methods) * [Response](#response) - - ## Getting Started This package is useful to consume API's, here is the instruction for installation and usage. @@ -53,7 +47,7 @@ This package is useful to consume API's, here is the instruction for installatio composer require lde/api-helper 3. This command will install package with dependency - + ## Configuration - To use this apihelper need to export config file to do so run the following command in your terminal to publish config file to config folder. diff --git a/dev-docker-compose.yaml b/develop-docker-compose.yaml similarity index 55% rename from dev-docker-compose.yaml rename to develop-docker-compose.yaml index f8d35c5..0a1134a 100644 --- a/dev-docker-compose.yaml +++ b/develop-docker-compose.yaml @@ -1,8 +1,10 @@ services: api-helper: - image: circleci/php:7.4 + build: + context: . + dockerfile: develop.Dockerfile container_name: api-helper working_dir: /app - command: sleep infinity volumes: - .:/app + - /app/vendor diff --git a/develop.Dockerfile b/develop.Dockerfile new file mode 100644 index 0000000..2eb8742 --- /dev/null +++ b/develop.Dockerfile @@ -0,0 +1,62 @@ +FROM circleci/php:7.4-cli + +# Install system dependencies +USER root +RUN apt-get update && apt-get install -y \ + git \ + curl \ + libxml2-dev \ + zip \ + unzip + +# Install PHP extensions including PCOV for code coverage +RUN pecl install pcov && \ + docker-php-ext-enable pcov && \ + docker-php-ext-install xml + +# Install Composer +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +# Set working directory +WORKDIR /app + +# Copy all files (excluding vendor directory due to .dockerignore) +COPY . . + +# Install dependencies (update if lock file is out of sync) +RUN composer update --no-scripts --prefer-dist --no-autoloader + +# Generate autoload files +RUN composer dump-autoload --optimize + +# Create a script to run composer install when container starts +RUN echo '#!/bin/bash\n\ +echo "Running startup script..."\n\ +git config --global --add safe.directory /app\n\ +composer install\n\ +echo "Starting container..."\n\ +sleep infinity' > /start.sh && chmod +x /start.sh + +# Create a wrapper script for running tests with coverage +RUN echo '#!/bin/bash\n\ +# Disable Xdebug by default for better performance\n\ +export PHP_IDE_CONFIG=\n\ +\n\ +# Enable Xdebug only when needed for coverage\n\ +if [ "$1" = "coverage" ]; then\n\ + echo "Enabling Xdebug for coverage report..."\n\ + php -d xdebug.mode=coverage ./vendor/bin/phpunit --configuration develop.phpunit.xml --coverage-html=coverage\n\ +else\n\ + # Run tests without Xdebug for better performance\n\ + echo "Running tests without Xdebug for better performance..."\n\ + php -n -d extension=/usr/local/lib/php/extensions/no-debug-non-zts-20190902/pcov.so ./vendor/bin/phpunit --configuration develop.phpunit.xml\n\ +fi' > /usr/local/bin/run-tests.sh && chmod +x /usr/local/bin/run-tests.sh + +# Create executable scripts for easier test command execution +RUN echo '#!/bin/bash\n\ +/usr/local/bin/run-tests.sh "$@"' > /usr/local/bin/test && chmod +x /usr/local/bin/test && \ +echo '#!/bin/bash\n\ +/usr/local/bin/run-tests.sh coverage "$@"' > /usr/local/bin/test-coverage && chmod +x /usr/local/bin/test-coverage + +# Keep container running +CMD ["/start.sh"] diff --git a/develop.phpunit.xml b/develop.phpunit.xml new file mode 100644 index 0000000..5877a78 --- /dev/null +++ b/develop.phpunit.xml @@ -0,0 +1,25 @@ + + + + + tests + + + + + src + + src/Config + + + + diff --git a/developer.README.md b/developer.README.md new file mode 100644 index 0000000..3e7e8d8 --- /dev/null +++ b/developer.README.md @@ -0,0 +1,205 @@ + +
+

+ + Logo + + +

Api Helper Package - Developer Guide

+ +

+ A package to consume api smoothly +
+ Explore the docs » +
+
+ View Package + · + Report Bug + · + Request Feature +

+

+ + + + +## Table of Contents + +* [Getting Started](#getting-started) +* [Installation](#installation) +* [Configuration](#configuration) +* [Usage](#usage) + * [Methods](#methods) +* [Response](#response) +* [Docker Development Setup](#docker-development-setup) + * [Prerequisites](#prerequisites) + * [Getting Started](#getting-started-1) + * [Volume Mounting](#volume-mounting) + * [Running Tests](#running-tests) + * [Running Tests with Coverage](#running-tests-with-coverage) + * [Development Workflow](#development-workflow) + + +## Getting Started + +This package is useful to consume API's, here is the instruction for installation and usage. + +## Installation + +1. To install this package using [Packagist](https://packagist.org/packages/lde/api-helper) + +2. On the root of your project run following command + + composer require lde/api-helper + +3. This command will install package with dependency + +## Configuration + +- To use this apihelper need to export config file to do so run the following command in your terminal to publish config file to config folder. + + php artisan vendor:publish --provider="Lde\ApiHelper\ApiHelperServiceProvider" + +- This will publish config file naming **api_helper.php** into config folder. + +## Prometheus Configuration +- Prometheus is dependent on your app so you need to provide prometheus configuration and also use below packages on your app. + + - [jimdo/prometheus_client_php](https://github.com/Jimdo/prometheus_client_php) + - [superbalist/laravel-prometheus-exporter](https://github.com/Superbalist/laravel-prometheus-exporter) +- If you want to use prometheus then you should turn it on from config [api_helper](src/Config/api_helper.php) +```php +'log_stats' => true, // If you want to use prometheus then set as true otherwise false + + 'prometheus' => [ + 'labels' => [ + 'client_id' => 10, + 'app' => 'api-helper', + 'source' => 'core', + ], + 'histogram_bucket' => [0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 7.5, 10.0], + ], +``` +- You can configure labels of prometheus inside `prometheus.labels` as per your need. +- `histogram_bucket` you can set inside prometheus config as array. + +## Usage + +- To use this package you need to add following class where you want to use this package. + + use Lde\ApiHelper\ApiBuilder; + + +### Methods + +#### addHeaders($headers) + +- This method is use to add headers. + +- It accept name and value as parameter, Here you can set only one header at a time. + + + $headers['Accept'] = "application/json"; + $headers['Content-Type'] = "application/json"; + app(ApiBuilder::class)->addHeaders($headers); + +- We will get response in form of object of ApiBuilder. + + +#### api($connection) + +- This method is use to set api that we are going to use from *api_helper.php* , there is httpbin and mokbin is define so you have to pass the name that you want to use. + +- You can also define your own api end point at *api_helper.php* in config file. + + app(ApiBuilder::class)->api('httpbin')->method_to_call(); + +- The snippet indicates how you can connect particular api and access their method. + +- method_to_call() is the function that you have specified inside *api_helper* connection array. + +- This will return object of ApiResponse. + +### Response + +- Here you will get object in response, In each response you will get success either true or false +- You will also get status code for more information about response please check below doc. +- http://docs.guzzlephp.org/en/latest/psr7.html#responses + +## Docker Development Setup + +This package includes a Docker development environment for easier testing and development. + +### Prerequisites + +- Docker and Docker Compose installed on your system + +### Getting Started + +1. Build and start the Docker container: + ```bash + docker-compose -f develop-docker-compose.yaml up -d + ``` + +2. Enter the container to work with the code: + ```bash + docker exec -it api-helper bash + ``` + +3. Inside the container, the package will automatically install dependencies using Composer on first run. + +### Volume Mounting + +The current directory is mounted to `/app` in the container. The `vendor` directory is excluded from the volume mount to prevent conflicts between host and container dependencies. + +### Running Tests + +You can run the PHPUnit tests using our optimized wrapper script: + +```bash +docker exec api-helper /usr/local/bin/run-tests.sh +``` + +The tests run without Xdebug by default for better performance. PCOV is used for code coverage collection when needed. +The tests use the `develop.phpunit.xml` configuration file which is optimized for the Docker development environment. + +### Running Tests with Coverage + +To run tests with code coverage reporting: + +```bash +docker exec api-helper /usr/local/bin/run-tests.sh coverage +``` + +This will generate an HTML coverage report in the `coverage` directory, which you can view by opening `coverage/index.html` in a web browser. + +Note: Coverage reports require Xdebug to be enabled, which will slow down test execution. For regular development, use the standard test command for better performance. + +### Using Test Aliases + +For convenience, the Docker container includes executable scripts for running tests: + +```bash +# Run tests without coverage (faster) +docker-compose -f develop-docker-compose.yaml exec api-helper test + +# Run tests with coverage report +docker-compose -f develop-docker-compose.yaml exec api-helper test-coverage +``` + +These commands can be run directly from your host machine without entering the container. + +You can also use them inside the container: + +```bash +docker exec -it api-helper bash +test # Run tests without coverage +test-coverage # Run tests with coverage +``` + +### Development Workflow + +1. Make changes to the code on your host machine +2. The changes will be immediately reflected in the container +3. Run tests or other commands inside the container as needed \ No newline at end of file diff --git a/src/ApiBuilder.php b/src/ApiBuilder.php index b45d80b..73f9eab 100644 --- a/src/ApiBuilder.php +++ b/src/ApiBuilder.php @@ -676,7 +676,7 @@ protected function maskFieldValues(array &$data, array $paths) $string = Arr::get($data, $field); - if (stripos($string, '@') !== false) { + if ($string !== null && stripos($string, '@') !== false) { $obfuscatedString = ObfuscationHelper::obfuscate($string, 4); } else { $obfuscatedString = ObfuscationHelper::obfuscate($string, 4); diff --git a/src/Helpers/ObfuscationHelper.php b/src/Helpers/ObfuscationHelper.php index 71df2dc..8e3aeaa 100644 --- a/src/Helpers/ObfuscationHelper.php +++ b/src/Helpers/ObfuscationHelper.php @@ -7,6 +7,11 @@ class ObfuscationHelper public static function obfuscate($string, $visibleChars = 4) { + // Handle null input + if ($string === null) { + return ''; + } + $len = strlen($string); $visible = substr($string, ($visibleChars * -1)); return str_pad($visible, $len, '*', STR_PAD_LEFT); @@ -14,6 +19,11 @@ public static function obfuscate($string, $visibleChars = 4) public static function obfuscateEmail($email) { + // Handle null input + if ($email === null) { + return ''; + } + $em = explode("@", $email); $name = implode('@', array_slice($em, 0, (count($em) - 1))); $len = (strlen($name) - 1);