https://github.com/brann-meius/flag-forge
High-performance PHP library for managing bitwise enumerations and flag operations—ideal for access control, configuration, and fast boolean state management.
https://github.com/brann-meius/flag-forge
bitwise bitwise-operations configuration efficiency enumeration enums flags performance php
Last synced: 5 months ago
JSON representation
High-performance PHP library for managing bitwise enumerations and flag operations—ideal for access control, configuration, and fast boolean state management.
- Host: GitHub
- URL: https://github.com/brann-meius/flag-forge
- Owner: brann-meius
- License: mit
- Created: 2025-02-26T10:59:06.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-03-12T12:37:53.000Z (10 months ago)
- Last Synced: 2025-07-11T13:59:19.867Z (6 months ago)
- Topics: bitwise, bitwise-operations, configuration, efficiency, enumeration, enums, flags, performance, php
- Language: PHP
- Homepage:
- Size: 43 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Flag Forge Package
[](https://github.com/brann-meius/flag-forge/actions)
[](https://codecov.io/gh/brann-meius/flag-forge)
[](https://app.codacy.com/gh/brann-meius/flag-forge/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[](LICENSE)
[](https://www.php.net/)
## Table of Contents
- [Overview](#overview)
- [Requirements](#requirements)
- [Getting Started](#getting-started)
- [Installation](#installation)
- [Usage](#usage)
- [Working with FlagManager](#working-with-flagmanager)
- [Database Integration Example](#database-integration-example)
- [Table Schema: chat_user](#table-schema-chat_user)
- [Sample Records](#sample-records)
- [Example Query: Checking a Specific Permission](#example-query-checking-a-specific-permission)
- [Example PHP Code Using PDO](#example-php-code-using-pdo)
- [API Reference](#api-reference)
- [Support](#support)
- [License](#license)
## Overview
The `meius/flag-forge` package provides an intuitive API for defining and managing bitwise enumerations in PHP. By
assigning power-of-two values to each flag, the package allows you to combine multiple flags using bitwise operators and
efficiently check individual flags using simple methods.
## Requirements
- PHP >= 8.1
## Getting Started
To get started with the `meius/flag-forge` package, follow the installation instructions below and check out the usage
examples.
## Installation
1. Install the package via Composer:
```bash
composer require meius/flag-forge
```
## Usage
Below is an example enum and how to work with the FlagManager.
```php
enum Permission: int implements Bitwiseable
{
case SendMessages = 1 << 0; // 1
case DeleteMessages = 1 << 1; // 2
case AddUsers = 1 << 2; // 4
case RemoveUsers = 1 << 3; // 8
case PinMessages = 1 << 4; // 16
case ManageChat = 1 << 5; // 32
case ManageModerators = 1 << 6; // 64
}
```
### Working with FlagManager
```php
use Meius\FlagForge\FlagManager;
$manager = new FlagManager();
$manager->getMask(); // Initial mask: 0
// ----------------------------------------------------------------------
// ADD FLAGS
// ----------------------------------------------------------------------
$manager->add(Permission::SendMessages) // - The bit corresponding to SendMessages is not set, so it gets added.
->add(Permission::AddUsers) // - The bit for AddUsers is not set, so it is added.
->add(Permission::AddUsers) // - Already set.
->add(Permission::PinMessages) // - The bit for PinMessages is not set, so it is added.
->getMask(); // Expected mask: 21 (SendMessages=1, AddUsers=4, PinMessages=16: 1+4+16=21)
// ----------------------------------------------------------------------
// COMBINE FLAGS
// ----------------------------------------------------------------------
$manager->combine(
Permission::SendMessages, // Already set.
Permission::DeleteMessages, // Not set; will be added.
Permission::AddUsers // Already set.
)->getMask(); // Expected mask: 23 (SendMessages=1, DeleteMessages=2, AddUsers=4, PinMessages=16: 21+2=23)
// ----------------------------------------------------------------------
// REMOVE FLAGS
// ----------------------------------------------------------------------
$manager->remove(Permission::AddUsers) // - Remove AddUsers: bit is set, so it will be removed.
->remove(Permission::ManageModerators) // - Remove ManageModerators: bit is not set, so nothing changes.
->getMask(); // Expected mask: 19
// ----------------------------------------------------------------------
// TOGGLE FLAGS
// ----------------------------------------------------------------------
$manager->toggle(
Permission::SendMessages, // Bit is set; toggled off.
Permission::DeleteMessages, // Bit is set; toggled off.
Permission::AddUsers, // Bit is not set; toggled on.
Permission::RemoveUsers // Bit is not set; toggled on.
)->getMask(); // Expected mask: 28
// ----------------------------------------------------------------------
// CHECK FLAGS
// ----------------------------------------------------------------------
$manager->has(Permission::SendMessages); // false
$manager->has(Permission::AddUsers); // true
$manager->doesntHave(Permission::SendMessages); // true
$manager->doesntHave(Permission::AddUsers); // false
// ----------------------------------------------------------------------
// ITERATE OVER ACTIVE FLAGS
// ----------------------------------------------------------------------
foreach ($manager as $flag) {
/**
* Example output:
* Active flag: AddUsers (4)
* Active flag: RemoveUsers (8)
* Active flag: PinMessages (16)
*/
echo "Active flag: " . $flag->name . " (" . $flag->value . ")" . PHP_EOL;
}
// ----------------------------------------------------------------------
// CLEAR FLAGS
// ----------------------------------------------------------------------
$manager->clear(); // Expected mask: 0
```
## Database Integration Example
FlagForge can be easily integrated with a database. The following example demonstrates how to store and retrieve a flag
mask using PDO.
### Database Schema and Usage Example
The following section describes the `chat_user` table schema used to store user permissions as a bitmask,
provides a few sample records, and shows an example of how to query the database to check a specific permission.
### Table Schema: chat_user
| Column | Data Type | Constraints | Description |
|-------------|------------------|------------------------|----------------------------------------|
| id | UUID | PRIMARY KEY | Unique identifier for the record. |
| chat_id | UUID | FOREIGN KEY, NOT NULL | Identifier of the chat. |
| user_id | UUID | FOREIGN KEY, NOT NULL | Identifier of the user. |
| permissions | UNSIGNED TINYINT | NOT NULL, DEFAULT (17) | Bitmask representing user permissions. |
### Sample Records
Below are a few example rows inserted into the `chat_user` table:
| id | chat_id | user_id | permissions |
|--------------------------------------|-----------|-----------|-------------|
| 11111111-1111-1111-1111-111111111111 | chat-1234 | user-1234 | 21 |
| 22222222-2222-2222-2222-222222222222 | chat-1234 | user-5678 | 23 |
| 33333333-3333-3333-3333-333333333333 | chat-4321 | user-9876 | 5 |
### Example Query: Checking a Specific Permission
Suppose you want to check if a specific user in a chat has the "SendMessages" permission.
Assume that the `SendMessages` permission corresponds to the bit value `1` (i.e. `1 << 0`).
The following SQL query uses the bitwise AND operator to verify that the permission bit is set:
```sql
SELECT *
FROM chat_user
WHERE chat_id = :chat_id
AND user_id = :user_id
AND (permissions & :flag) = :flag;
```
### Example PHP Code Using PDO
Below is an example of how you might execute the above query using a PDO instance (assumed to be available as `$pdo`):
```php
use Meius\FlagForge\FlagManager;
/**
* @var PDO $pdo
* @var FlagManager $manager
* @var string $chatId Chat ID to query.
* @var string $userId User ID to query.
*/
$manager->add(Permission::SendMessages);
// Prepare the SQL statement
$stmt = $pdo->prepare('
SELECT *
FROM chat_user
WHERE chat_id = :chat_id
AND user_id = :user_id
AND (permissions & :flag) = :flag
');
// Execute the query with the parameters
$stmt->execute([
':chat_id' => $chatId,
':user_id' => $userId,
':flag' => $manager,
]);
// Fetch the result
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result) {
echo "User has the SendMessages permission.";
} else {
echo "User does NOT have the SendMessages permission.";
}
```
## API Reference
### FlagManager
- `add(Bitwiseable $flag): self` — Adds a flag to the current mask.
- `remove(Bitwiseable $flag): self` — Removes a flag from the current mask.
- `combine(Bitwiseable ...$flags): self` — Combines multiple flags into the current mask.
- `toggle(Bitwiseable ...$flags): self` — Toggles specified flags.
- `clear(): self` — Clears all flags in the current mask.
- `has(Bitwiseable $flag): bool` — Checks if the specified flag is present.
- `doesntHave(Bitwiseable $flag): bool` — Checks if the specified flag is not present.
- `getMask(): int` — Returns the current mask value.
- `toArray(): array` — Returns an array representation of the current mask.
## Support
For support, please open an issue on the [GitHub repository](https://github.com/brann-meius/flag-forge/issues).
### Contributing
We welcome contributions to the `meius/flag-forge` library. To contribute, follow these steps:
1. **Fork the Repository**: Fork the repository on GitHub and clone it to your local machine.
2. **Create a Branch**: Create a new branch for your feature or bugfix.
3. **Write Tests**: Write tests to cover your changes.
4. **Run Tests**: Ensure all tests pass by running `phpunit`.
5. **Submit a Pull Request**: Submit a pull request with a clear description of your changes.
For more details, refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file.
## License
This package is open-sourced software licensed under the [MIT license](LICENSE).