File: /var/www/html/wp-content/plugins/wp-graphql/src/Mutation/UpdateSettings.php
<?php
namespace WPGraphQL\Mutation;
use GraphQL\Error\UserError;
use WPGraphQL\Data\DataSource;
use WPGraphQL\Registry\TypeRegistry;
use WPGraphQL\Utils\Utils;
/**
* Class UpdateSettings
*
* @package WPGraphQL\Mutation
*/
class UpdateSettings {
/**
* Registers the CommentCreate mutation.
*
* @param \WPGraphQL\Registry\TypeRegistry $type_registry The WPGraphQL TypeRegistry
*
* @return void
*/
public static function register_mutation( TypeRegistry $type_registry ) {
$output_fields = self::get_output_fields( $type_registry );
$input_fields = self::get_input_fields( $type_registry );
if ( empty( $output_fields ) || empty( $input_fields ) ) {
return;
}
register_graphql_mutation(
'updateSettings',
[
'inputFields' => $input_fields,
'outputFields' => $output_fields,
'mutateAndGetPayload' => static function ( $input ) use ( $type_registry ) {
return self::mutate_and_get_payload( $input, $type_registry );
},
]
);
}
/**
* Defines the mutation input field configuration.
*
* @param \WPGraphQL\Registry\TypeRegistry $type_registry The WPGraphQL TypeRegistry
*
* @return array<string,array<string,mixed>>
*/
public static function get_input_fields( TypeRegistry $type_registry ) {
$allowed_settings = DataSource::get_allowed_settings( $type_registry );
$input_fields = [];
if ( ! empty( $allowed_settings ) ) {
/**
* Loop through the $allowed_settings and build fields
* for the individual settings
*/
foreach ( $allowed_settings as $key => $setting ) {
if ( ! isset( $setting['type'] ) || ! $type_registry->get_type( $setting['type'] ) ) {
continue;
}
/**
* Determine if the individual setting already has a
* REST API name, if not use the option name.
* Sanitize the field name to be camelcase
*/
if ( ! empty( $setting['show_in_rest']['name'] ) ) {
$individual_setting_key = lcfirst( $setting['group'] . 'Settings' . str_replace( '_', '', ucwords( $setting['show_in_rest']['name'], '_' ) ) );
} else {
$individual_setting_key = lcfirst( $setting['group'] . 'Settings' . str_replace( '_', '', ucwords( $key, '_' ) ) );
}
$replaced_setting_key = graphql_format_name( $individual_setting_key, ' ', '/[^a-zA-Z0-9 -]/' );
if ( ! empty( $replaced_setting_key ) ) {
$individual_setting_key = $replaced_setting_key;
}
$individual_setting_key = lcfirst( $individual_setting_key );
$individual_setting_key = lcfirst( str_replace( '_', ' ', ucwords( $individual_setting_key, '_' ) ) );
$individual_setting_key = lcfirst( str_replace( '-', ' ', ucwords( $individual_setting_key, '_' ) ) );
$individual_setting_key = lcfirst( str_replace( ' ', '', ucwords( $individual_setting_key, ' ' ) ) );
/**
* Dynamically build the individual setting,
* then add it to the $input_fields
*/
$input_fields[ $individual_setting_key ] = [
'type' => $setting['type'],
'description' => $setting['description'],
];
}
}
return $input_fields;
}
/**
* Defines the mutation output field configuration.
*
* @param \WPGraphQL\Registry\TypeRegistry $type_registry The WPGraphQL TypeRegistry
*
* @return array<string,array<string,mixed>>
*/
public static function get_output_fields( TypeRegistry $type_registry ) {
/**
* Get the allowed setting groups and their fields
*/
$allowed_setting_groups = DataSource::get_allowed_settings_by_group( $type_registry );
$output_fields = [];
/**
* Get all of the settings, regardless of group
*/
$output_fields['allSettings'] = [
'type' => 'Settings',
'description' => static function () {
return __( 'Update all settings.', 'wp-graphql' );
},
'resolve' => static function () {
return true;
},
];
if ( ! empty( $allowed_setting_groups ) && is_array( $allowed_setting_groups ) ) {
foreach ( $allowed_setting_groups as $group => $setting_type ) {
$setting_type = DataSource::format_group_name( $group );
$setting_type_name = Utils::format_type_name( $setting_type . 'Settings' );
$output_fields[ Utils::format_field_name( $setting_type_name ) ] = [
'type' => $setting_type_name,
// translators: %s is the setting type name
'description' => static function () use ( $setting_type_name ) {
// translators: %s is the setting type name
return sprintf( __( 'Update the %s setting.', 'wp-graphql' ), $setting_type_name );
},
'resolve' => static function () use ( $setting_type_name ) {
return $setting_type_name;
},
];
}
}
return $output_fields;
}
/**
* Defines the mutation data modification closure.
*
* @param array<string,mixed> $input The mutation input
* @param \WPGraphQL\Registry\TypeRegistry $type_registry The WPGraphQL TypeRegistry
*
* @return array<string,array<string,string>>
*
* @throws \GraphQL\Error\UserError
*/
public static function mutate_and_get_payload( array $input, TypeRegistry $type_registry ): array {
/**
* Check that the user can manage setting options
*/
if ( ! current_user_can( 'manage_options' ) ) {
throw new UserError( esc_html__( 'Sorry, you are not allowed to edit settings as this user.', 'wp-graphql' ) );
}
/**
* The $updatable_settings_options will store all of the allowed
* settings in a WP ready format
*/
$updatable_settings_options = [];
$allowed_settings = DataSource::get_allowed_settings( $type_registry );
/**
* Loop through the $allowed_settings and build the insert options array
*/
foreach ( $allowed_settings as $key => $setting ) {
/**
* Determine if the individual setting already has a
* REST API name, if not use the option name.
* Sanitize the field name to be camelcase
*/
if ( isset( $setting['show_in_rest']['name'] ) && ! empty( $setting['show_in_rest']['name'] ) ) {
$individual_setting_key = lcfirst( $setting['group'] . 'Settings' . str_replace( '_', '', ucwords( $setting['show_in_rest']['name'], '_' ) ) );
} else {
$individual_setting_key = lcfirst( $setting['group'] . 'Settings' . str_replace( '_', '', ucwords( $key, '_' ) ) );
}
/**
* Dynamically build the individual setting,
* then add it to $updatable_settings_options
*/
$updatable_settings_options[ Utils::format_field_name( $individual_setting_key ) ] = [
'option' => $key,
'group' => $setting['group'],
];
}
foreach ( $input as $key => $value ) {
/**
* Throw an error if the input field is the site url,
* as we do not want users changing it and breaking all
* the things
*/
if ( 'generalSettingsUrl' === $key ) {
throw new UserError( esc_html__( 'Sorry, that is not allowed, speak with your site administrator to change the site URL.', 'wp-graphql' ) );
}
/**
* Check to see that the input field exists in settings, if so grab the option
* name and update the option
*/
if ( array_key_exists( $key, $updatable_settings_options ) ) {
update_option( $updatable_settings_options[ $key ]['option'], $value );
}
}
return $updatable_settings_options;
}
}