From ab683b47de458158cf937e5a53bb949bb06c77f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jakes=CC=8C?= Date: Mon, 13 May 2019 14:34:47 +0200 Subject: [PATCH] Add feature flags API [MAILPOET-2008] --- lib/API/JSON/v1/FeatureFlags.php | 45 +++++++++++++++++++ lib/Config/AccessControl.php | 8 ++++ lib/DI/ContainerConfigurator.php | 1 + lib/Features/FeatureFlagsController.php | 38 ++++++++++++++++ lib/Models/FeatureFlag.php | 10 +++++ .../integration/Config/AccessControlTest.php | 9 ++++ 6 files changed, 111 insertions(+) create mode 100644 lib/API/JSON/v1/FeatureFlags.php create mode 100644 lib/Features/FeatureFlagsController.php diff --git a/lib/API/JSON/v1/FeatureFlags.php b/lib/API/JSON/v1/FeatureFlags.php new file mode 100644 index 0000000000..10899e4f01 --- /dev/null +++ b/lib/API/JSON/v1/FeatureFlags.php @@ -0,0 +1,45 @@ + AccessControl::PERMISSION_MANAGE_FEATURES, + ]; + + function __construct(FeatureFlagsController $feature_flags) { + $this->feature_flags_controller = $feature_flags; + } + + function getAll() { + $feature_flags = $this->feature_flags_controller->getAll(); + return $this->successResponse($feature_flags); + } + + function set(array $flags) { + foreach ($flags as $name => $value) { + if (!isset(FeaturesController::$defaults[$name])) { + return $this->badRequest([ + APIError::BAD_REQUEST => "Feature '$name' does not exist'", + ]); + } + } + + foreach ($flags as $name => $value) { + $this->feature_flags_controller->set($name, (bool)$value); + } + return $this->successResponse([]); + } +} diff --git a/lib/Config/AccessControl.php b/lib/Config/AccessControl.php index ed3b1fe6b2..4f1e234256 100644 --- a/lib/Config/AccessControl.php +++ b/lib/Config/AccessControl.php @@ -8,6 +8,7 @@ if (!defined('ABSPATH')) exit; class AccessControl { const PERMISSION_ACCESS_PLUGIN_ADMIN = 'mailpoet_access_plugin_admin'; const PERMISSION_MANAGE_SETTINGS = 'mailpoet_manage_settings'; + const PERMISSION_MANAGE_FEATURES = 'mailpoet_manage_features'; const PERMISSION_MANAGE_EMAILS = 'mailpoet_manage_emails'; const PERMISSION_MANAGE_SUBSCRIBERS = 'mailpoet_manage_subscribers'; const PERMISSION_MANAGE_FORMS = 'mailpoet_manage_forms'; @@ -30,6 +31,12 @@ class AccessControl { 'administrator' ) ), + self::PERMISSION_MANAGE_FEATURES => WPFunctions::get()->applyFilters( + 'mailpoet_permission_manage_features', + array( + 'administrator' + ) + ), self::PERMISSION_MANAGE_EMAILS => WPFunctions::get()->applyFilters( 'mailpoet_permission_manage_emails', array( @@ -62,6 +69,7 @@ class AccessControl { return array( self::PERMISSION_ACCESS_PLUGIN_ADMIN => WPFunctions::get()->__('Admin menu item', 'mailpoet'), self::PERMISSION_MANAGE_SETTINGS => WPFunctions::get()->__('Manage settings', 'mailpoet'), + self::PERMISSION_MANAGE_FEATURES => WPFunctions::get()->__('Manage features', 'mailpoet'), self::PERMISSION_MANAGE_EMAILS => WPFunctions::get()->__('Manage emails', 'mailpoet'), self::PERMISSION_MANAGE_SUBSCRIBERS => WPFunctions::get()->__('Manage subscribers', 'mailpoet'), self::PERMISSION_MANAGE_FORMS => WPFunctions::get()->__('Manage forms', 'mailpoet'), diff --git a/lib/DI/ContainerConfigurator.php b/lib/DI/ContainerConfigurator.php index dc8400bdae..d135e61d65 100644 --- a/lib/DI/ContainerConfigurator.php +++ b/lib/DI/ContainerConfigurator.php @@ -39,6 +39,7 @@ class ContainerConfigurator implements IContainerConfigurator { $container->autowire(\MailPoet\API\JSON\v1\Analytics::class)->setPublic(true); $container->autowire(\MailPoet\API\JSON\v1\AutomatedLatestContent::class)->setPublic(true); $container->autowire(\MailPoet\API\JSON\v1\CustomFields::class)->setPublic(true); + $container->autowire(\MailPoet\API\JSON\v1\FeatureFlags::class)->setPublic(true); $container->autowire(\MailPoet\API\JSON\v1\Forms::class)->setPublic(true); $container->autowire(\MailPoet\API\JSON\v1\ImportExport::class)->setPublic(true); $container->autowire(\MailPoet\API\JSON\v1\Mailer::class)->setPublic(true); diff --git a/lib/Features/FeatureFlagsController.php b/lib/Features/FeatureFlagsController.php new file mode 100644 index 0000000000..bb1eb8341e --- /dev/null +++ b/lib/Features/FeatureFlagsController.php @@ -0,0 +1,38 @@ + $name, + 'value' => $value , + ]); + + if ($result->getErrors()) { + throw new \RuntimeException("Error when saving feature '$name''"); + } + } + + function getAll() { + $flags = FeatureFlag::findArray(); + $flagsMap = array_combine(array_column($flags, 'name'), $flags); + + $output = []; + foreach (FeaturesController::$defaults as $name => $default) { + $output[] = [ + 'name' => $name, + 'value' => isset($flagsMap[$name]) ? (bool)$flagsMap[$name]['value'] : $default, + 'default' => $default, + ]; + } + return $output; + } +} diff --git a/lib/Models/FeatureFlag.php b/lib/Models/FeatureFlag.php index e536e60718..9510157d99 100644 --- a/lib/Models/FeatureFlag.php +++ b/lib/Models/FeatureFlag.php @@ -9,4 +9,14 @@ if (!defined('ABSPATH')) exit; */ class FeatureFlag extends Model { public static $_table = MP_FEATURE_FLAGS_TABLE; + + static function createOrUpdate($data = []) { + $keys = false; + if (isset($data['name'])) { + $keys = [ + 'name' => $data['name'], + ]; + } + return parent::_createOrUpdate($data, $keys); + } } diff --git a/tests/integration/Config/AccessControlTest.php b/tests/integration/Config/AccessControlTest.php index 8c129e48dd..085e14cbfc 100644 --- a/tests/integration/Config/AccessControlTest.php +++ b/tests/integration/Config/AccessControlTest.php @@ -31,6 +31,12 @@ class AccessControlTest extends \MailPoetTest { return array('custom_manage_settings_role'); } ); + $wp->addFilter( + 'mailpoet_permission_manage_features', + function() { + return array('custom_manage_features_role'); + } + ); $wp->addFilter( 'mailpoet_permission_manage_emails', function() { @@ -64,6 +70,9 @@ class AccessControlTest extends \MailPoetTest { AccessControl::PERMISSION_MANAGE_SETTINGS => array( 'custom_manage_settings_role' ), + AccessControl::PERMISSION_MANAGE_FEATURES => array( + 'custom_manage_features_role' + ), AccessControl::PERMISSION_MANAGE_EMAILS => array( 'custom_manage_emails_role' ),