PHPackages                             baraja-core/selectbox-tree - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. baraja-core/selectbox-tree

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

baraja-core/selectbox-tree
==========================

Simple tree builder to plain selectbox array.

v2.2.1(4y ago)366.5k[1 issues](https://github.com/baraja-core/selectbox-tree/issues)3PHPPHP ^8.0CI failing

Since Jul 14Pushed 4mo agoCompare

[ Source](https://github.com/baraja-core/selectbox-tree)[ Packagist](https://packagist.org/packages/baraja-core/selectbox-tree)[ Docs](https://github.com/baraja-core/selectbox-tree)[ RSS](/packages/baraja-core-selectbox-tree/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (7)Versions (16)Used By (3)

Selectbox Tree
==============

[](#selectbox-tree)

Simple and elegant tree builder that transforms hierarchical data structures into flat selectbox-friendly arrays with visual indentation.

[![Sample selectbox view](doc/selectbox-design.png)](doc/selectbox-design.png)

✨ Key Features
--------------

[](#sparkles-key-features)

- Transforms parent-child tree structures into flat arrays suitable for HTML `` elements
- Automatic visual indentation using pipe characters (`|`) and non-breaking spaces to represent hierarchy depth
- Built-in SQL query builder helper for fetching hierarchical data from databases
- Configurable maximum depth to prevent infinite recursion
- Custom name formatting through the `NameFormatter` interface
- Optional integration with `Baraja\Localization\Translation` for multilingual support
- Supports both raw array input and typed `SelectboxItem` objects
- Zero external dependencies (PHP 8.0+ only)

🏗️ Architecture
---------------

[](#building_construction-architecture)

The library consists of three main components:

```
┌─────────────────────────────────────────────────────────────┐
│                      SelectboxTree                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  process(array $data): array                        │   │
│  │  - Accepts SelectboxItem[] or raw arrays            │   │
│  │  - Builds hierarchical structure                    │   │
│  │  - Returns flat array with visual indentation       │   │
│  └─────────────────────────────────────────────────────┘   │
│                           │                                 │
│                           ▼                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  serializeCategoriesToSelectbox()                   │   │
│  │  - Recursive tree traversal                         │   │
│  │  - Tracks used IDs to prevent duplicates            │   │
│  │  - Respects maxDepth limit                          │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
           │                               │
           ▼                               ▼
┌─────────────────────┐       ┌─────────────────────────┐
│   SelectboxItem     │       │    NameFormatter        │
│  ┌───────────────┐  │       │      (interface)        │
│  │ id            │  │       │  ┌───────────────────┐  │
│  │ name          │  │       │  │ format(string):   │  │
│  │ parentId      │  │       │  │   string          │  │
│  └───────────────┘  │       │  └───────────────────┘  │
└─────────────────────┘       └─────────────────────────┘

```

### 🧩 Components Overview

[](#jigsaw-components-overview)

ComponentTypeDescription`SelectboxTree`ClassMain processor that converts tree data to selectbox array`SelectboxItem`ClassImmutable value object representing a single tree node`NameFormatter`InterfaceContract for custom name transformation logic⚙️ How It Works
---------------

[](#gear-how-it-works)

### Tree Transformation Process

[](#tree-transformation-process)

The library takes hierarchical data where each item has an `id`, `name`, and optional `parent_id`, then:

1. **Normalizes input** - Accepts either `SelectboxItem` objects or raw associative arrays
2. **Applies name formatting** - If a `NameFormatter` is set, transforms each item's name
3. **Builds tree recursively** - Starting from root items (where `parent_id` is `null`), traverses children depth-first
4. **Generates visual indentation** - Prepends pipe characters and non-breaking spaces based on depth level
5. **Returns flat array** - Keys are item IDs, values are formatted names with indentation

### Visual Indentation Format

[](#visual-indentation-format)

Each level of depth adds the pattern `|   ` (pipe followed by three non-breaking spaces):

```
Root Item
|   First Level Child
|   |   Second Level Child
|   |   |   Third Level Child

```

### Input Data Format

[](#input-data-format)

The `process()` method accepts an array of items in two formats:

**Array format:**

```
[
    ['id' => 1, 'name' => 'Electronics', 'parent_id' => null],
    ['id' => 2, 'name' => 'Phones', 'parent_id' => 1],
    ['id' => 3, 'name' => 'iPhone', 'parent_id' => 2],
]
```

**SelectboxItem format:**

```
[
    new SelectboxItem(1, 'Electronics', null),
    new SelectboxItem(2, 'Phones', 1),
    new SelectboxItem(3, 'iPhone', 2),
]
```

### Output Format

[](#output-format)

The `process()` method returns an associative array where:

- **Keys** are the original item IDs (`int|string`)
- **Values** are the formatted names with visual indentation (`string`)

```
[
    1 => 'Electronics',
    2 => '|   Phones',
    3 => '|   |   iPhone',
]
```

📦 Installation
--------------

[](#package-installation)

It's best to use [Composer](https://getcomposer.org) for installation, and you can also find the package on [Packagist](https://packagist.org/packages/baraja-core/selectbox-tree) and [GitHub](https://github.com/baraja-core/selectbox-tree).

To install, simply use the command:

```
$ composer require baraja-core/selectbox-tree
```

You can use the package manually by creating an instance of the internal classes, or register a DIC extension to link the services directly to the Nette Framework.

### Requirements

[](#requirements)

- PHP 8.0 or higher

🚀 Basic Usage
-------------

[](#rocket-basic-usage)

### Simple Example

[](#simple-example)

```
use Baraja\SelectboxTree\SelectboxTree;

$tree = new SelectboxTree();

$data = [
    ['id' => 1, 'name' => 'Main category', 'parent_id' => null],
    ['id' => 2, 'name' => 'Phone', 'parent_id' => 1],
    ['id' => 3, 'name' => 'iPhone', 'parent_id' => 2],
    ['id' => 4, 'name' => 'Computer', 'parent_id' => 1],
    ['id' => 5, 'name' => 'Mac', 'parent_id' => 4],
    ['id' => 6, 'name' => 'MacBook', 'parent_id' => 5],
    ['id' => 7, 'name' => 'iMac', 'parent_id' => 5],
    ['id' => 8, 'name' => 'Windows', 'parent_id' => 4],
];

$selectboxOptions = $tree->process($data);

// Result:
// [
//     1 => 'Main category',
//     2 => '|   Phone',
//     3 => '|   |   iPhone',
//     4 => '|   Computer',
//     5 => '|   |   Mac',
//     6 => '|   |   |   MacBook',
//     7 => '|   |   |   iMac',
//     8 => '|   |   Windows',
// ]
```

### Using with HTML Select Element

[](#using-with-html-select-element)

```
use Baraja\SelectboxTree\SelectboxTree;

$tree = new SelectboxTree();
$options = $tree->process($categories);

echo '';
foreach ($options as $id => $name) {
    echo sprintf('%s', $id, htmlspecialchars($name));
}
echo '';
```

### Using SelectboxItem Objects

[](#using-selectboxitem-objects)

```
use Baraja\SelectboxTree\SelectboxTree;
use Baraja\SelectboxTree\SelectboxItem;

$tree = new SelectboxTree();

$items = [
    new SelectboxItem(1, 'Electronics', null),
    new SelectboxItem(2, 'Phones', 1),
    new SelectboxItem(3, 'Computers', 1),
];

$selectboxOptions = $tree->process($items);
```

🔧 Advanced Configuration
------------------------

[](#wrench-advanced-configuration)

### Setting Maximum Depth

[](#setting-maximum-depth)

To prevent infinite recursion or limit the tree depth, use `setMaxDepth()`:

```
$tree = new SelectboxTree();
$tree->setMaxDepth(5); // Limit to 5 levels deep

$options = $tree->process($data);
```

**Constraints:**

- Minimum value: `1`
- Maximum value: `1000`
- Default value: `32`

### Custom Name Formatting

[](#custom-name-formatting)

Implement the `NameFormatter` interface to transform item names:

```
use Baraja\SelectboxTree\SelectboxTree;
use Baraja\SelectboxTree\NameFormatter;

class UppercaseFormatter implements NameFormatter
{
    public function format(string $name): string
    {
        return strtoupper($name);
    }
}

$tree = new SelectboxTree();
$tree->setNameFormatter(new UppercaseFormatter());

$options = $tree->process($data);
// All names will be uppercase
```

### SQL Query Builder

[](#sql-query-builder)

The library includes a helper method to generate SQL queries for fetching hierarchical data:

```
$tree = new SelectboxTree();

// Basic usage
$sql = $tree->sqlBuilder('categories');
// SELECT `id`, `name`, `parent_id` FROM `categories` ORDER BY `name` ASC

// Custom columns
$sql = $tree->sqlBuilder(
    table: 'products',
    primaryCol: 'title',
    parentCol: 'category_id',
);
// SELECT `id`, `title`, `category_id` FROM `products` ORDER BY `title` ASC

// With WHERE conditions
$sql = $tree->sqlBuilder(
    table: 'categories',
    wheres: ['active = 1', 'deleted_at IS NULL'],
);
// SELECT `id`, `name`, `parent_id` FROM `categories`
// WHERE (active = 1) AND (deleted_at IS NULL) ORDER BY `name` ASC

// Custom ORDER BY
$sql = $tree->sqlBuilder(
    table: 'categories',
    orderCol: 'position',
);
// SELECT `id`, `name`, `parent_id` FROM `categories` ORDER BY `position` ASC
```

**Parameters:**

ParameterTypeDefaultDescription`$table``string`requiredDatabase table name`$primaryCol``string``'name'`Column containing the display name`$parentCol``string``'parent_id'`Column containing the parent reference`$wheres``array``[]`Array of WHERE conditions`$orderCol``?string``null`Column for ORDER BY (defaults to `$primaryCol`)### Integration with Database

[](#integration-with-database)

```
use Baraja\SelectboxTree\SelectboxTree;

$tree = new SelectboxTree();

// Generate SQL query
$sql = $tree->sqlBuilder('categories', 'name', 'parent_id', ['active = 1']);

// Fetch data from database (using your preferred method)
$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
$stmt = $pdo->query($sql);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Process into selectbox format
$options = $tree->process($data);
```

🌐 Localization Support
----------------------

[](#globe_with_meridians-localization-support)

The library automatically integrates with `Baraja\Localization\Translation` if available. Names starting with `T:{` pattern are automatically translated:

```
$data = [
    ['id' => 1, 'name' => 'T:{"cs":"Kategorie","en":"Category"}', 'parent_id' => null],
];

$tree = new SelectboxTree();
$options = $tree->process($data);
// The name will be automatically translated based on current locale
```

This feature is optional and only activates when the `baraja-core/localization` package is installed.

🛡️ Safety Features
------------------

[](#shield-safety-features)

### Duplicate Prevention

[](#duplicate-prevention)

The library tracks processed IDs to prevent duplicate entries in the output, even if the same item appears multiple times in the input data.

### Infinite Recursion Protection

[](#infinite-recursion-protection)

Two mechanisms prevent infinite loops:

1. **Max depth limit** - Configurable via `setMaxDepth()`, defaults to 32 levels
2. **Used ID tracking** - Items are only processed once, preventing circular references

### Input Validation

[](#input-validation)

- Max depth must be between 1 and 1000
- Empty or null input arrays are handled gracefully (return empty array)

👥 Author
--------

[](#busts_in_silhouette-author)

**Jan Barasek**

📄 License
---------

[](#page_facing_up-license)

`baraja-core/selectbox-tree` is licensed under the MIT license. See the [LICENSE](https://github.com/baraja-core/selectbox-tree/blob/master/LICENSE) file for more details.

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance45

Moderate activity, may be stable

Popularity26

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 96.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~63 days

Recently: every ~109 days

Total

11

Last Release

1489d ago

Major Versions

v1.1.2 → v2.0.02021-01-02

PHP version history (5 changes)v1.0.0PHP &gt;=7.1.0

v1.1.0PHP &gt;=7.4.0

v2.0.0PHP &gt;=8.0.0

v2.0.1PHP ^7.4 || ^8.0

v2.1.0PHP ^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3382204?v=4)[baraja](/maintainers/baraja)[@baraja](https://github.com/baraja)

---

Top Contributors

[![janbarasek](https://avatars.githubusercontent.com/u/4738758?v=4)](https://github.com/janbarasek "janbarasek (58 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (1 commits)")[![imgbot[bot]](https://avatars.githubusercontent.com/in/4706?v=4)](https://github.com/imgbot[bot] "imgbot[bot] (1 commits)")

---

Tags

categoriescategoryhtml-selectselectboxtreetree-selectboxtree-structure

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/baraja-core-selectbox-tree/health.svg)

```
[![Health](https://phpackages.com/badges/baraja-core-selectbox-tree/health.svg)](https://phpackages.com/packages/baraja-core-selectbox-tree)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
