Skip to content
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
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_size = 2
6 changes: 5 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.editorconfig export-ignore
.gitignore export-ignore
tests export-ignore
docs export-ignore
.github export-ignore
Expand All @@ -7,5 +9,7 @@ phpunit.xml export-ignore
pint.json export-ignore
rector.php export-ignore
.gitattributes export-ignore
psalm.xml export-ignore
pest.xml export-ignore

* text eol=lf
* text eol=lf
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @abmmhasan
* @abmmhasan
6 changes: 3 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: 2
updates:
- package-ecosystem: "composer" # See documentation for possible values
directory: "/" # Location of package manifests
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "daily"
interval: "weekly"
79 changes: 69 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,34 @@ on:
schedule:
- cron: '0 0 * * 0'
push:
branches: [ '*' ]
branches: [ "main", "master" ]
pull_request:
branches: [ "main", "master", "develop" ]
branches: [ "main", "master", "develop", "development" ]

jobs:
prepare:
name: Prepare CI matrix
runs-on: ubuntu-latest
outputs:
php_versions: ${{ steps.matrix.outputs.php_versions }}
dependency_versions: ${{ steps.matrix.outputs.dependency_versions }}
steps:
- name: Define shared matrix values
id: matrix
run: |
echo 'php_versions=["8.3","8.4","8.5"]' >> "$GITHUB_OUTPUT"
echo 'dependency_versions=["prefer-lowest","prefer-stable"]' >> "$GITHUB_OUTPUT"

run:
needs: prepare
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: [ ubuntu-latest ]
php-versions: [ '8.2', '8.3', '8.4' ]
dependency-version: [ prefer-lowest, prefer-stable ]
php-versions: ${{ fromJson(needs.prepare.outputs.php_versions) }}
dependency-version: ${{ fromJson(needs.prepare.outputs.dependency_versions) }}

name: PHP ${{ matrix.php-versions }} - ${{ matrix.operating-system }} - ${{ matrix.dependency-version }}
name: Code Analysis - PHP ${{ matrix.php-versions }} - ${{ matrix.dependency-version }}
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -35,11 +49,56 @@ jobs:
- name: Validate Composer
run: composer validate --strict

- name: Resolve dependencies (${{ matrix.dependency-version }})
run: composer update --no-interaction --prefer-dist --no-progress --${{ matrix.dependency-version }}

- name: Test
run: |
composer test:code
composer test:lint
composer test:refactor
# Skip Psalm on prefer-lowest: older transitive amphp versions can trigger PHP 8.4+ deprecations at startup.
if [ "${{ matrix.dependency-version }}" != "prefer-lowest" ]; then
composer test:security
fi

analyze:
needs: prepare
name: Security Analysis - PHP ${{ matrix.php-versions }}
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ${{ fromJson(needs.prepare.outputs.php_versions) }}
permissions:
security-events: write
actions: read
contents: read

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

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
tools: composer:v2

- name: Install dependencies
run: composer install --no-interaction --prefer-dist --optimize-autoloader
run: composer install --no-interaction --prefer-dist --no-progress

- name: Package Audit
run: composer audit
- name: Composer Audit (CVE check)
run: composer audit --no-interaction

- name: Test
run: composer tests
# Run Psalm (Deep Taint Analysis)
- name: Run Psalm Security Scan
run: |
php ./vendor/bin/psalm --config=psalm.xml --security-analysis --threads=1 --report=psalm-results.sarif || true
continue-on-error: true

- name: Upload Psalm Results
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: psalm-results.sarif
category: "psalm-${{ matrix.php-versions }}"
if: always() && hashFiles('psalm-results.sarif') != ''
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@ test.php
composer.lock
git-story_media
*~
diffs.txt
*.txt
!docs/requirements.txt
.windsurf
.vscode
.phpunit.cache
var
*.patch
patch.php
.psalm-cache
AI_CONTEXT.md
18 changes: 18 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2

build:
os: ubuntu-24.04
tools:
python: "3.13"

python:
install:
- requirements: docs/requirements.txt

sphinx:
configuration: docs/conf.py

formats:
- pdf
- epub

50 changes: 12 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,23 @@
![Packagist Version](https://img.shields.io/packagist/v/infocyph/arraykit)
![Packagist PHP Version](https://img.shields.io/packagist/dependency-v/infocyph/arraykit/php)
![GitHub Code Size](https://img.shields.io/github/languages/code-size/infocyph/arraykit)
[![Documentation](https://img.shields.io/badge/Documentation-ArrayKit-blue?logo=readthedocs&logoColor=white)](https://docs.infocyph.com/projects/arraykit/)

**ArrayKit** is a modern **PHP 8.2+** library for elegant, high-performance **array manipulation**, **dot notation
**ArrayKit** is a modern **PHP 8.4+** library for elegant, high-performance **array manipulation**, **dot notation
utilities**, **dynamic configuration**, **hookable collections**, and more.
From shallow single arrays to deeply nested data structures — **ArrayKit** provides a fluent, reliable toolkit for
real-world PHP projects.

---

## 📦 Features at a Glance

✅ **Single-Dimensional Helpers**
✅ **Multi-Dimensional Helpers**
✅ **Dot Notation Get/Set/Flatten**
✅ **Dynamic Config with Hooks**
✅ **Collection & Hooked Collection**
✅ **Traits for DTO & Hooking**
✅ **Pipeline for Collection Ops**
✅ **Global Helpers (`functions.php`)**

---
- **Single-Dimensional Helpers**
- **Multi-Dimensional Helpers**
- **Dot Notation Get/Set/Flatten**
- **Dynamic Config with Hooks**
- **Collection & Hooked Collection**
- **Traits for DTO & Hooking**
- **Pipeline for Collection Ops**
- **Global Helpers (`functions.php`)**

## 📚 Modules

Expand All @@ -39,17 +36,14 @@ real-world PHP projects.
| **DotNotation** | Get/set/remove values using dot keys; flatten & expand nested arrays with dot keys. |
| **BaseArrayHelper** | Internal shared base for consistent API across helpers. |

---

### ➤ Config System

| Class | Description |
|---------------------|---------------------------------------------------------------------------------------------------------------------|
| **Config** | Immutable dot-access configuration loader. |
| **Config** | Dot-access configuration loader. |
| **DynamicConfig** | Extends `Config` with **on-get/on-set hooks** to transform values dynamically (e.g., encrypt/decrypt, auto-format). |
| **BaseConfigTrait** | Shared config logic. |

---

### ➤ Collections

Expand All @@ -60,7 +54,6 @@ real-world PHP projects.
| **Pipeline** | Functional-style pipeline for chaining operations on collections. |
| **BaseCollectionTrait** | Shared collection behavior. |

---

### ➤ Traits

Expand All @@ -69,30 +62,25 @@ real-world PHP projects.
| **HookTrait** | Generic hook system for on-get/on-set callbacks. Used by `DynamicConfig` & `HookedCollection`. |
| **DTOTrait** | Utility trait for DTO-like behavior: populate, extract, cast arrays/objects easily. |

---

### ➤ Global Helpers

| File | Description |
|-------------------|------------------------------------------------------------|
| **functions.php** | Global shortcut functions for frequent array/config tasks. |

---

## ✅ Requirements

* **PHP 8.2** or higher
* **PHP 8.4** or higher

---

## ⚡ Installation

```bash
composer require infocyph/arraykit
```

---

## 🚀 Quick Examples

### 🔹 Single-Dimensional Helpers
Expand All @@ -112,8 +100,6 @@ $dupes = ArraySingle::duplicates($list); // [2]
$page = ArraySingle::paginate($list, page:1, perPage:2); // [1, 2]
```

---

### 🔹 Multi-Dimensional Helpers

```php
Expand All @@ -134,8 +120,6 @@ $depth = ArrayMulti::depth($data); // 3
$sorted = ArrayMulti::sortRecursive($data);
```

---

### 🔹 Dot Notation

```php
Expand All @@ -156,8 +140,6 @@ $flat = DotNotation::flatten($user);
// [ 'profile.name' => 'Alice', 'profile.email' => 'alice@example.com' ]
```

---

### 🔹 Dynamic Config with Hooks

```php
Expand All @@ -179,8 +161,6 @@ $config->set('auth.password', 'secret123');
$hashed = $config->get('auth.password');
```

---

### 🔹 Hooked Collection

```php
Expand All @@ -200,8 +180,6 @@ $collection['role'] = 'admin';
echo $collection['role']; // Role: admin
```

---

### 🔹 DTO Trait Example

```php
Expand All @@ -219,14 +197,10 @@ $user->fromArray(['name' => 'Alice', 'email' => 'alice@example.com']);
$array = $user->toArray();
```

---

## 🤝 Support

Have a bug or feature idea? Please [open an issue](https://github.com/infocyph/arraykit/issues).

---

## 📄 License

Licensed under the **MIT License** — use it freely for personal or commercial projects. See [LICENSE](LICENSE) for
Expand Down
Loading
Loading