magmasoftwareengineering / rollout-group-slim
Slim 4 integration for magmasoftwareengineering/rollout — feature flag admin controllers, multi-storage replication, Twig helpers, and a Symfony Console command. Successor to the previous opensoft/rollout-based wrapper.
Package info
bitbucket.org/magmasoftwareengineering/rollout-group-slim
pkg:composer/magmasoftwareengineering/rollout-group-slim
Requires
- php: >=8.3 || >=8.5
- akrabat/ip-address-middleware: ^2.6
- kanellov/slim-twig-flash: ^0.2.0
- league/csv: ^9.28
- magmasoftwareengineering/rollout: ^3.0
- magmasoftwareengineering/slim-base: ^3.2
- magmasoftwareengineering/slim-module-middleware: ^2.1
- slim/http: ^1.4
- symfony/console: ^7.4 || ^8.0
Requires (Dev)
- codeception/codeception: ^5.3
- codeception/module-asserts: ^3.3
- roave/security-advisories: dev-latest
- 3.x-dev
- 3.2.1
- 3.2.0
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.1
- 3.0.0
- 2.x-dev
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.13
- 2.2.12
- 2.2.11
- 2.2.10
- 2.2.9
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.2
- 2.0.1
- 2.0.0
- 1.x-dev
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- 0.x-dev
- 0.5.1
- 0.5.0
- 0.4.2
- 0.4.1
- 0.4.0
- 0.3.2
- 0.3.1
- 0.3.0
- 0.2.3
- 0.2.2
- 0.2.1
- 0.0.1
- dev-feature/smoke-test-rollout-3.0
- dev-develop
- dev-php71
- dev-master
This package is auto-updated.
Last update: 2026-05-20 14:56:50 UTC
README
Version: 3.x | PHP: >=8.3 | License: MIT
Status
The original
opensoft/rolloutupstream has been unmaintained since 2017. This package now depends onmagmasoftwareengineering/rollout— the maintained successor — rather than the abandonedopensoft/rollout: ^2.3it wrapped previously. The engine package is at3.0.0and ships strict types, modernised storage adapters (including a rewrittenMongoDBStorageAdapterforext-mongodband a newPsr16StorageAdapter), a JSON wire format with backwards-compat reader, and real interfaces.The Slim integration here is unchanged in spirit: feature-flag admin controllers, multi-storage replication via
GroupDefinitionAwareRollout, Twig helpers, a Symfony Console command, and theFeatureFlaggableTrait. Existing call sites that target rollout's public API (isActive,activateGroup,activatePercentage, etc.) continue to work without changes.A parallel OpenFeature Provider is now available — see Forward direction below.
Overview
The Rollout Group Slim (magmasoftwareengineering/rollout-group-slim) provides feature flagging and user group management for Slim 4 applications. It builds on magmasoftwareengineering/rollout ^3.0 (the maintained successor to opensoft/rollout) to control feature availability, conduct A/B testing, and gradually roll features out to users or groups.
This library also builds upon Slim Base and Slim Module Middleware to provide enterprise-grade feature management capabilities.
Key Features
Feature Flagging
- Feature toggles - Control feature visibility at runtime
- Group-based activation - Target specific user groups for feature rollout
- Percentage rollout - Gradually roll out features to a percentage of users
- User-specific flags - Enable features for specific users or IDs
- Admin interface - Built-in UI for managing feature flags
Group Management
- Custom group definitions - Define custom user groups (e.g., "beta_users", "enterprise_customers")
- Group-definition-aware Rollout - Extend base Rollout with group support
- Closure-based groups - Flexible group definition using PHP closures
- Persistent storage - Support for multiple storage backends (Redis, database, etc.)
Integration
- Twig integration - Template helpers for conditional feature rendering
- Trait-based API -
FeatureFlaggableTraitfor adding flagging to controllers/services - CLI management - Console commands for managing feature flags
- CSV export/import - Bulk feature flag management
Dependencies
php: >=8.3
magmasoftwareengineering/slim-base: ^3.2 (HTTP controllers)
magmasoftwareengineering/slim-module-middleware: ^2.1 (Module system)
magmasoftwareengineering/rollout: ^3.0 (Feature flagging engine — successor to opensoft/rollout)
akrabat/ip-address-middleware: ^2.6 (IP address detection)
kanellov/slim-twig-flash: ^0.2.0 (Flash messages)
league/csv: ^9.28 (CSV handling)
slim/http: ^1.4 (HTTP utilities)
symfony/console: ^7.4 || ^8.0 (CLI framework)
Installation
composer require magmasoftwareengineering/rollout-group-slim:^3.0
This automatically includes:
magmasoftwareengineering/slim-base:^3.0magmasoftwareengineering/slim-module-middleware:^2.0- And all their dependencies
Usage Examples
Basic Feature Flagging
1. Define a Group
<?php
// src/modules/Features/GroupDefinition/BetaUsersGroup.php
namespace MyApp\Features\GroupDefinition;
use MagmaSoftwareEngineering\Rollout\Rollout\GroupDefinitionInterface;
class BetaUsersGroup implements GroupDefinitionInterface {
public function getName(): string {
return 'beta_users';
}
public function getCallback(): callable {
return function($user) {
// $user is typically a user ID or User entity
// Return true if user is in the beta group
return in_array($user, [1, 2, 3, 4, 5], true);
};
}
}
2. Add Feature to Container
<?php
// src/modules/Features/dependencies.php
use DI\Container;
use MyApp\Features\GroupDefinition\BetaUsersGroup;
return static function (Container $container): void {
$container->set(BetaUsersGroup::class, new BetaUsersGroup());
};
3. Register Group with Rollout
<?php
// Initialize in your bootstrap or controller
/** @var GroupDefinitionAwareRollout $rollout */
$rollout->addGroupDefinition($container->get(BetaUsersGroup::class));
Using Feature Flags in Controllers
<?php
// src/modules/Features/Controller/FeatureController.php
namespace MyApp\Features\Controller;
use MagmaSoftwareEngineering\Slim\Controller\AbstractController;
use MagmaSoftwareEngineering\Rollout\Interfaces\FeatureFlaggableInterface;
use MagmaSoftwareEngineering\Rollout\Interfaces\RolloutInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class FeatureController extends AbstractController implements FeatureFlaggableInterface {
use FeatureFlaggableTrait;
public function getFeatures(Request $request, Response $response): Response {
$userId = $this->getCurrentUserId();
$features = [];
// Check if feature is active for this user
if ($this->getFeatureFlagging()->isActive('new_dashboard', $userId)) {
$features['new_dashboard'] = true;
}
// Check if feature is active for a group
if ($this->getFeatureFlagging()->isActiveInGroup('beta_features', 'beta_users', $userId)) {
$features['beta_features'] = true;
}
// Percentage-based rollout
if ($this->getFeatureFlagging()->isActive('gradual_rollout', $userId, 10)) {
// Only 10% of users see this feature
$features['gradual_rollout'] = true;
}
return $this->jsonResponse($response, $features);
}
private function getCurrentUserId(): int {
// Get current user ID from authentication service
return $this->entityManager
->getRepository(User::class)
->findOneBy(['email' => $this->getAttribute('user_email')])
->getId();
}
}
Using in Twig Templates
The library provides Twig extensions for easy feature flag checking:
{# templates/dashboard.twig #}
{% if rollout_is_active('new_dashboard', user.id) %}
<div class="new-dashboard">
{# New dashboard UI #}
{{ include('components/new_dashboard.twig') }}
</div>
{% else %}
<div class="old-dashboard">
{# Legacy dashboard UI #}
{{ include('components/old_dashboard.twig') }}
</div>
{% endif %}
{# Group-based flags #}
{% if rollout_is_active_in_group('beta_features', 'beta_users', user.id) %}
<button class="beta-feature">Try Beta Features</button>
{% endif %}
Feature Management Commands
The library includes CLI commands for managing features:
# List all features
php console.php rollout:group:list
# Activate a feature for a user
php console.php rollout:group:activate --feature=new_dashboard --user=123
# Activate a feature for a group
php console.php rollout:group:activate --feature=beta_features --group=beta_users
# Deactivate a feature
php console.php rollout:group:deactivate --feature=new_dashboard --user=123
# Import features from CSV
php console.php rollout:group:import features.csv
# Export features to CSV
php console.php rollout:group:export features.csv
Advanced: Custom User Provider
Create a custom user provider to dynamically determine group membership:
<?php
// src/modules/Features/Service/CustomUserProvider.php
namespace MyApp\Features\Service;
use MagmaSoftwareEngineering\Rollout\Rollout\UserProviderInterface;
use Doctrine\ORM\EntityManagerInterface;
class CustomUserProvider implements UserProviderInterface {
public function __construct(private EntityManagerInterface $em) {}
public function isUserInGroup(string $userId, string $groupName): bool {
$user = $this->em->find(User::class, $userId);
if (!$user) {
return false;
}
return match($groupName) {
'beta_users' => $user->isBetaTester(),
'enterprise' => $user->getAccountType() === 'enterprise',
'admin' => $user->hasRole('ADMIN'),
default => false,
};
}
}
Feature Flag Entity
Features are stored using RolloutFeature entity:
<?php
// Example: creating a feature programmatically
use MagmaSoftwareEngineering\Rollout\Entity\RolloutFeature;
$feature = new RolloutFeature();
$feature->setName('new_dashboard');
$feature->setDescription('New dashboard interface');
$feature->setPercentage(50); // Rollout to 50% of users
$feature->setActive(true);
$this->entityManager->persist($feature);
$this->entityManager->flush();
Complete Application Example
Directory Structure
my-api/
├── src/
│ └── modules/
│ ├── Features/
│ │ ├── src/
│ │ │ ├── Controller/
│ │ │ │ ├── FeatureController.php
│ │ │ │ └── AdminController.php
│ │ │ ├── Service/
│ │ │ │ └── FeatureService.php
│ │ │ ├── GroupDefinition/
│ │ │ │ ├── BetaUsersGroup.php
│ │ │ │ ├── EnterpriseGroup.php
│ │ │ │ └── AdminGroup.php
│ │ │ └── dependencies.php
│ │ ├── Module.php
│ │ ├── routes.php
│ │ └── settings.php
│ └── User/
│ └── ...
├── public/
│ └── index.php
└── config/
└── bootstrap.php
Module Routes
<?php
// src/modules/Features/routes.php
use Slim\Routing\RouteCollectorProxy;
use MyApp\Features\Controller\FeatureController;
use MyApp\Features\Controller\AdminController;
return static function (RouteCollectorProxy $app): void {
// Public feature flag endpoints
$app->group('/features', function (RouteCollectorProxy $group) {
$group->get('', [FeatureController::class, 'getFeatures']);
$group->post('', [FeatureController::class, 'create']);
});
// Admin feature management
$app->group('/admin/features', function (RouteCollectorProxy $group) {
$group->get('', [AdminController::class, 'list']);
$group->get('/{id}', [AdminController::class, 'show']);
$group->put('/{id}', [AdminController::class, 'update']);
$group->delete('/{id}', [AdminController::class, 'delete']);
$group->post('/import', [AdminController::class, 'import']);
$group->get('/export', [AdminController::class, 'export']);
});
};
Integration with Other Libraries
| Library | Purpose | Integration |
|---|---|---|
| Slim Base | HTTP controllers & settings | Extend AbstractController & implement FeatureFlaggableInterface |
| Slim Module Middleware | Module system | Loaded as a module with routes & controllers |
| Doctrine Base | Database entities & repositories | Uses RolloutFeature entity |
| PHP DebugBar Middleware | Developer debugging | Feature flags visible in debug bar |
Forward direction — OpenFeature
A separate package, magmasoftwareengineering/rollout-openfeature-provider, bridges the rollout engine to the OpenFeature evaluation API. Slim applications can use both surfaces side-by-side:
- This package continues to provide the admin controllers, Twig helpers, console command, and
FeatureFlaggableTraitfor rollout-shaped management of flags. - An OpenFeature
Client, configured with theRolloutProvider, gives application code a vendor-neutral evaluation surface ($client->getBooleanValue,$client->getStringValue, etc.) backed by the sameRolloutinstance.
use MagmaSoftwareEngineering\Rollout\OpenFeature\RolloutProvider;
use OpenFeature\OpenFeatureAPI;
$api = OpenFeatureAPI::getInstance();
$api->setProvider(new RolloutProvider($rollout)); // same $rollout this package wires up
$client = $api->getClient('my-slim-app');
$client->getBooleanValue('chat', false);
The provider supports boolean flags as a direct delegate to Rollout::isActive, and typed flags (string / integer / float / object) via a data['value'] convention on Feature::getData(). The closure-based group definitions this wrapper provides via defineGroup() don't currently map onto OpenFeature's declarative targeting model — see docs/06-openfeature-native-replacement.md for the long-term path being explored.
Architecture
Rollout Group Slim Library
├── Feature Flagging
│ ├── GroupDefinitionAwareRollout (extends magmasoftwareengineering/rollout)
│ ├── RolloutFeature Entity
│ └── CLI Commands
├── Group Management
│ ├── GroupDefinitionInterface
│ ├── Custom group definitions
│ └── Closure-based rules
├── Twig Integration
│ ├── RolloutIsActiveExtension
│ └── RolloutIsActiveInGroupExtension
└── Controllers
├── Feature management UI
└── Admin dashboard
Use Cases
1. Gradual Rollout
// Gradually rollout new feature to 10% → 25% → 50% → 100%
$rollout->isActive('new_feature', $userId, 10); // Week 1
$rollout->isActive('new_feature', $userId, 25); // Week 2
$rollout->isActive('new_feature', $userId, 50); // Week 3
$rollout->isActive('new_feature', $userId, 100); // Week 4
2. Beta Testing
// Enable features only for beta testers
$rollout->isActiveInGroup('beta_feature', 'beta_users', $userId);
3. A/B Testing
// Test variant A vs variant B
if ($rollout->isActive('feature_variant_a', $userId, 50)) {
// Show variant A to 50% of users
} else {
// Show variant B to other 50%
}
4. Internal/Admin Features
// Feature only visible to admins
$rollout->isActiveInGroup('admin_panel', 'admins', $userId);
Related Libraries
- Slim Base Library - HTTP controllers
- Slim Module Middleware - Module system
- PHP DebugBar Middleware - Developer tools
- Base Library - Core utilities
Support & Contributing
For issues or contributions, please contact the maintainer:
- Jeremy Coates - hello@phpcodemonkey.me.uk
License
MIT License - See LICENSE file for details