baraja-core / selectbox-tree
Simple tree builder to plain selectbox array.
Installs: 66 499
Dependents: 3
Suggesters: 0
Security: 0
Stars: 3
Watchers: 0
Forks: 1
Open Issues: 1
pkg:composer/baraja-core/selectbox-tree
Requires
- php: ^8.0
Requires (Dev)
- phpstan/extension-installer: ^1.1
- phpstan/phpstan: ^1.0
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-nette: ^1.0
- phpstan/phpstan-strict-rules: ^1.0
- roave/security-advisories: dev-master
- spaze/phpstan-disallowed-calls: ^2.0
This package is auto-updated.
Last update: 2026-01-04 10:46:00 UTC
README
Simple and elegant tree builder that transforms hierarchical data structures into flat selectbox-friendly arrays with visual indentation.
β¨ Key Features
- Transforms parent-child tree structures into flat arrays suitable for HTML
<select>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
NameFormatterinterface - Optional integration with
Baraja\Localization\Translationfor multilingual support - Supports both raw array input and typed
SelectboxItemobjects - Zero external dependencies (PHP 8.0+ only)
ποΈ 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
| Component | Type | Description |
|---|---|---|
SelectboxTree |
Class | Main processor that converts tree data to selectbox array |
SelectboxItem |
Class | Immutable value object representing a single tree node |
NameFormatter |
Interface | Contract for custom name transformation logic |
βοΈ How It Works
Tree Transformation Process
The library takes hierarchical data where each item has an id, name, and optional parent_id, then:
- Normalizes input - Accepts either
SelectboxItemobjects or raw associative arrays - Applies name formatting - If a
NameFormatteris set, transforms each item's name - Builds tree recursively - Starting from root items (where
parent_idisnull), traverses children depth-first - Generates visual indentation - Prepends pipe characters and non-breaking spaces based on depth level
- Returns flat array - Keys are item IDs, values are formatted names with indentation
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
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
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
It's best to use Composer for installation, and you can also find the package on Packagist and GitHub.
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
- PHP 8.0 or higher
π Basic Usage
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
use Baraja\SelectboxTree\SelectboxTree; $tree = new SelectboxTree(); $options = $tree->process($categories); echo '<select name="category">'; foreach ($options as $id => $name) { echo sprintf('<option value="%s">%s</option>', $id, htmlspecialchars($name)); } echo '</select>';
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
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
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
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:
| Parameter | Type | Default | Description |
|---|---|---|---|
$table |
string |
required | Database 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
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
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
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
Two mechanisms prevent infinite loops:
- Max depth limit - Configurable via
setMaxDepth(), defaults to 32 levels - Used ID tracking - Items are only processed once, preventing circular references
Input Validation
- Max depth must be between 1 and 1000
- Empty or null input arrays are handled gracefully (return empty array)
π₯ Author
Jan Barasek https://baraja.cz
π License
baraja-core/selectbox-tree is licensed under the MIT license. See the LICENSE file for more details.
