Skip to content

Commit 6f89bd5

Browse files
committed
Refactoring
1 parent 379f3de commit 6f89bd5

5 files changed

Lines changed: 644 additions & 253 deletions

File tree

src/RestApi.php

Lines changed: 16 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use WP_Error;
1717
use WP_REST_Request;
1818
use WP_REST_Response;
19+
use WP_User_Query;
1920

2021
/**
2122
* Class RestApi
@@ -843,7 +844,7 @@ protected static function handle_user_search( WP_REST_Request $request ): WP_RES
843844
$args['search_columns'] = [ 'user_login', 'user_email', 'display_name' ];
844845
}
845846

846-
$user_query = new \WP_User_Query( $args );
847+
$user_query = new WP_User_Query( $args );
847848
$results = [];
848849

849850
foreach ( $user_query->get_results() as $user ) {
@@ -895,103 +896,27 @@ protected static function format_results( $results ): WP_REST_Response {
895896
*/
896897
public static function handle_license( WP_REST_Request $request ) {
897898
$settings_id = $request->get_param( 'settings_id' );
898-
$field_key = $request->get_param( 'field_key' );
899-
$key = $request->get_param( 'key' );
900-
$action = $request->get_param( 'action' );
901-
902-
$field = self::get_field_config( $settings_id, $field_key );
903-
904-
if ( ! $field ) {
905-
return new WP_Error(
906-
'invalid_field',
907-
__( 'Invalid field configuration.', 'setting-fields' ),
908-
[ 'status' => 400 ]
909-
);
910-
}
911-
912-
if ( ( $field['type'] ?? '' ) !== 'license' ) {
913-
return new WP_Error(
914-
'invalid_field_type',
915-
__( 'Field is not a license type.', 'setting-fields' ),
916-
[ 'status' => 400 ]
917-
);
918-
}
919-
920-
$callback = $field['callback'] ?? null;
899+
$instance = Registry::instance()->get( $settings_id );
921900

922-
if ( ! is_callable( $callback ) ) {
901+
if ( ! $instance ) {
923902
return new WP_Error(
924-
'invalid_callback',
925-
__( 'No callback defined for this license field.', 'setting-fields' ),
926-
[ 'status' => 500 ]
903+
'invalid_settings',
904+
__( 'Settings not found.', 'setting-fields' ),
905+
[ 'status' => 404 ]
927906
);
928907
}
929908

930909
try {
931-
$data = [
932-
'settings_id' => $settings_id,
933-
'field_key' => $field_key,
934-
'key' => $key,
935-
'action' => $action,
936-
];
937-
938-
$result = call_user_func( $callback, $data );
939-
940-
// Normalize result
941-
if ( is_bool( $result ) ) {
942-
$result = [
943-
'success' => $result,
944-
'message' => $result
945-
? __( 'License action completed successfully.', 'setting-fields' )
946-
: __( 'License action failed.', 'setting-fields' ),
947-
];
948-
}
949-
950-
if ( is_string( $result ) ) {
951-
$result = [
952-
'success' => true,
953-
'message' => $result,
954-
];
955-
}
910+
$result = $instance->process_license(
911+
$request->get_param( 'field_key' ),
912+
$request->get_param( 'key' ),
913+
$request->get_param( 'action' )
914+
);
956915

957-
if ( $result instanceof WP_Error ) {
916+
if ( is_wp_error( $result ) ) {
958917
return $result;
959918
}
960919

961-
$result = wp_parse_args( (array) $result, [
962-
'success' => true,
963-
'message' => __( 'License action completed.', 'setting-fields' ),
964-
'status' => null,
965-
'expiry' => null,
966-
'url' => null,
967-
'url_label' => null,
968-
] );
969-
970-
// Persist status and expiry to the stored value
971-
if ( $result['status'] ) {
972-
$instance = Registry::instance()->get( $settings_id );
973-
974-
if ( $instance ) {
975-
$option_name = $instance->get_option_name();
976-
$options = get_option( $option_name, [] );
977-
$current = wp_parse_args( (array) ( $options[ $field_key ] ?? [] ), [
978-
'key' => '',
979-
'status' => 'inactive',
980-
'expiry' => '',
981-
] );
982-
983-
$current['key'] = $key;
984-
$current['status'] = sanitize_key( $result['status'] );
985-
986-
if ( $result['expiry'] !== null ) {
987-
$current['expiry'] = sanitize_text_field( $result['expiry'] );
988-
}
989-
990-
$options[ $field_key ] = $current;
991-
update_option( $option_name, $options );
992-
}
993-
}
994-
995920
return new WP_REST_Response( $result, $result['success'] ? 200 : 400 );
996921

997922
} catch ( Exception $e ) {
@@ -1028,38 +953,11 @@ public static function handle_reset( WP_REST_Request $request ) {
1028953
);
1029954
}
1030955

1031-
$fields = $instance->get_fields();
1032-
$option_name = $instance->get_option_name();
1033-
$current = get_option( $option_name, [] );
1034-
1035-
if ( ! is_array( $current ) ) {
1036-
$current = [];
1037-
}
1038-
1039-
$reset_count = 0;
1040-
$skip_types = [ 'message', 'html', 'separator', 'heading', 'action_button', 'clipboard' ];
1041-
1042-
foreach ( $fields as $field_key => $field ) {
1043-
// If a tab was specified, only reset fields on that tab
1044-
if ( ! empty( $tab ) && ( $field['tab'] ?? '' ) !== $tab ) {
1045-
continue;
1046-
}
1047-
1048-
// Skip layout-only fields that store nothing
1049-
if ( in_array( $field['type'] ?? '', $skip_types, true ) ) {
1050-
continue;
1051-
}
1052-
1053-
$current[ $field_key ] = $field['default'] ?? '';
1054-
$reset_count ++;
1055-
}
1056-
1057-
update_option( $option_name, $current );
956+
$reset_count = $instance->reset_settings( $tab ?? '' );
1058957

1059958
return new WP_REST_Response( [
1060959
'success' => true,
1061960
'message' => sprintf(
1062-
/* translators: %d: number of settings reset */
1063961
_n(
1064962
'%d setting reset to default.',
1065963
'%d settings reset to defaults.',
@@ -1166,47 +1064,9 @@ public static function handle_import( WP_REST_Request $request ) {
11661064
* @return array|null The field configuration or null if not found.
11671065
*/
11681066
protected static function get_field_config( string $settings_id, string $field_key ): ?array {
1169-
$settings = Registry::instance()->get( $settings_id );
1170-
1171-
if ( ! $settings ) {
1172-
return null;
1173-
}
1174-
1175-
$fields = $settings->get_fields();
1176-
1177-
// Check if this is a nested field path
1178-
if ( str_contains( $field_key, '.' ) ) {
1179-
$parts = explode( '.', $field_key );
1180-
$parent_key = $parts[0];
1181-
$child_key = $parts[1];
1182-
$parent_field = $fields[ $parent_key ] ?? null;
1183-
1184-
if ( ! $parent_field || ! isset( $parent_field['sub_fields'] ) ) {
1185-
return null;
1186-
}
1187-
1188-
return $parent_field['sub_fields'][ $child_key ] ?? null;
1189-
}
1190-
1191-
return $fields[ $field_key ] ?? null;
1192-
}
1193-
1194-
/**
1195-
* Get the REST namespace.
1196-
*
1197-
* @return string
1198-
*/
1199-
public static function get_namespace(): string {
1200-
return self::NAMESPACE;
1201-
}
1067+
$instance = Registry::instance()->get( $settings_id );
12021068

1203-
/**
1204-
* Get the full REST URL for ajax requests.
1205-
*
1206-
* @return string
1207-
*/
1208-
public static function get_rest_url(): string {
1209-
return rest_url( self::NAMESPACE . '/ajax' );
1069+
return $instance?->get_field( $field_key );
12101070
}
12111071

12121072
}

src/SettingFields.php

Lines changed: 17 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
use ArrayPress\RegisterSettingFields\Traits\SettingsRegistration;
2121
use ArrayPress\RegisterSettingFields\Traits\TabManager;
2222
use ArrayPress\RegisterSettingFields\Traits\ConditionalLogic;
23+
use ArrayPress\RegisterSettingFields\Traits\SettingsActions;
24+
use ArrayPress\RegisterSettingFields\Traits\EmailActions;
25+
use ArrayPress\RegisterSettingFields\Traits\DataPortability;
2326

2427
/**
2528
* Class SettingFields
@@ -36,6 +39,9 @@ class SettingFields {
3639
use SettingsRegistration;
3740
use TabManager;
3841
use ConditionalLogic;
42+
use SettingsActions;
43+
use EmailActions;
44+
use DataPortability;
3945

4046
/**
4147
* Unique identifier for this settings group.
@@ -845,112 +851,26 @@ public function get_fields(): array {
845851
/**
846852
* Get a specific field configuration.
847853
*
848-
* @param string $field_key Field key.
854+
* Supports dot notation for nested field paths (e.g., 'parent.child'
855+
* to access a sub_field within a repeater or group field).
856+
*
857+
* @param string $field_key Field key, optionally with dot notation.
849858
*
850859
* @return array|null
851860
*/
852861
public function get_field( string $field_key ): ?array {
853-
return $this->fields[ $field_key ] ?? null;
854-
}
855-
856-
/**
857-
* Export settings as a JSON-encodable array.
858-
*
859-
* Returns decrypted values for all non-constant fields. Encrypted fields
860-
* are exported in plain text so the JSON can be imported into another
861-
* environment (which may have different encryption keys).
862-
*
863-
* @return array
864-
*/
865-
public function export_settings(): array {
866-
$values = $this->get_values();
867-
$exported = [];
868-
869-
foreach ( $this->fields as $field_key => $field ) {
870-
// Skip fields that get their value from constants
871-
if ( $this->is_encrypted_field( $field ) && $this->has_field_constant( $field_key, $field ) ) {
872-
continue;
873-
}
874-
875-
// Skip layout fields that have no stored data
876-
if ( in_array( $field['type'] ?? '', [
877-
'message',
878-
'html',
879-
'separator',
880-
'heading',
881-
'hidden',
882-
'action_button',
883-
'clipboard'
884-
], true ) ) {
885-
continue;
886-
}
887-
888-
$exported[ $field_key ] = $values[ $field_key ] ?? ( $field['default'] ?? '' );
889-
}
890-
891-
return [
892-
'settings_id' => $this->id,
893-
'version' => 1,
894-
'exported_at' => current_time( 'mysql' ),
895-
'data' => $exported,
896-
];
897-
}
898-
899-
/**
900-
* Import settings from an exported array.
901-
*
902-
* Each field value is sanitized through the standard field sanitizer
903-
* before saving. Encrypted fields are re-encrypted with the current
904-
* environment's encryption key.
905-
*
906-
* @param array $import The import data (must contain 'data' key).
907-
*
908-
* @return bool|string True on success, error message on failure.
909-
*/
910-
public function import_settings( array $import ) {
911-
if ( empty( $import['data'] ) || ! is_array( $import['data'] ) ) {
912-
return __( 'Invalid import file: no data found.', 'setting-fields' );
913-
}
914-
915-
// Validate settings ID if present
916-
if ( ! empty( $import['settings_id'] ) && $import['settings_id'] !== $this->id ) {
917-
return sprintf(
918-
__( 'Import file is for "%s", not "%s".', 'setting-fields' ),
919-
$import['settings_id'],
920-
$this->id
921-
);
922-
}
923-
924-
$sanitized = [];
862+
if ( str_contains( $field_key, '.' ) ) {
863+
$parts = explode( '.', $field_key, 2 );
864+
$parent = $this->fields[ $parts[0] ] ?? null;
925865

926-
foreach ( $this->fields as $field_key => $field ) {
927-
if ( ! array_key_exists( $field_key, $import['data'] ) ) {
928-
continue;
866+
if ( ! $parent || ! isset( $parent['sub_fields'] ) ) {
867+
return null;
929868
}
930869

931-
$sanitized[ $field_key ] = $this->sanitize_field_value(
932-
$field_key,
933-
$field,
934-
$import['data'][ $field_key ]
935-
);
936-
}
937-
938-
if ( empty( $sanitized ) ) {
939-
return __( 'No valid fields found in import data.', 'setting-fields' );
940-
}
941-
942-
// Merge with existing values (don't blow away fields not in the export)
943-
$current = get_option( $this->config['option_name'], [] );
944-
945-
if ( ! is_array( $current ) ) {
946-
$current = [];
870+
return $parent['sub_fields'][ $parts[1] ] ?? null;
947871
}
948872

949-
$merged = array_merge( $current, $sanitized );
950-
951-
update_option( $this->config['option_name'], $merged );
952-
953-
return true;
873+
return $this->fields[ $field_key ] ?? null;
954874
}
955875

956876
}

0 commit comments

Comments
 (0)