Files
besttechfrom.eu/app/Http/Controllers/Admin/FeatureFlagController.php
T

128 lines
3.8 KiB
PHP
Raw Normal View History

2026-02-21 15:10:37 +02:00
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Laravel\Pennant\Feature;
class FeatureFlagController extends Controller
{
/**
* Display a listing of feature flags.
*/
public function index()
{
// Get all feature flag classes from app/Features directory
$featurePath = app_path('Features');
$features = [];
if (File::isDirectory($featurePath)) {
$files = File::files($featurePath);
foreach ($files as $file) {
$className = 'App\\Features\\' . $file->getFilenameWithoutExtension();
if (class_exists($className)) {
$featureName = $this->getFeatureName($className);
// Get the current state for null scope (global)
$isActive = Feature::for(null)->active($featureName);
$features[] = [
'name' => $featureName,
'class' => $className,
'is_active' => $isActive,
'description' => $this->getFeatureDescription($className),
];
}
}
}
// Sort features by name
usort($features, fn($a, $b) => strcmp($a['name'], $b['name']));
return view('admin.feature-flags.index', compact('features'));
}
/**
* Toggle a feature flag on or off.
*/
public function toggle(Request $request)
{
$validated = $request->validate([
'feature' => ['required', 'string'],
'active' => ['required', 'boolean'],
]);
$featureName = $validated['feature'];
// Activate or deactivate the feature for null scope (global)
if ($validated['active']) {
Feature::for(null)->activate($featureName);
$message = "Feature '{$featureName}' has been activated.";
} else {
Feature::for(null)->deactivate($featureName);
$message = "Feature '{$featureName}' has been deactivated.";
}
return redirect()->route('admin.feature-flags.index')
->with('success', $message);
}
/**
* Purge a feature flag (remove all stored values).
*/
public function purge(Request $request)
{
$validated = $request->validate([
'feature' => ['required', 'string'],
]);
$featureName = $validated['feature'];
Feature::purge($featureName);
return redirect()->route('admin.feature-flags.index')
->with('success', "Feature '{$featureName}' has been purged from storage.");
}
/**
* Get the feature name from the class.
*/
private function getFeatureName(string $className): string
{
// Check if class has Name attribute
$reflection = new \ReflectionClass($className);
$attributes = $reflection->getAttributes(\Laravel\Pennant\Attributes\Name::class);
if (!empty($attributes)) {
$nameAttribute = $attributes[0]->newInstance();
return $nameAttribute->name;
}
// Default to class basename
return class_basename($className);
}
/**
* Get the feature description from class docblock.
*/
private function getFeatureDescription(string $className): ?string
{
$reflection = new \ReflectionClass($className);
$docComment = $reflection->getDocComment();
if ($docComment) {
// Extract the first line of the docblock as description
preg_match('/\/\*\*\s*\n\s*\*\s*(.+?)\n/s', $docComment, $matches);
if (isset($matches[1])) {
return trim($matches[1]);
}
}
return null;
}
}