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 @@
+
+
+
+
+
+
+
+
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);