roles ); } if ( ! is_array( $provided[ $role_field ] ) ) { return new WP_Error( self::ERROR_PREFIX . 'invalid_' . $role_field, sprintf( /* translators: %s: the offending field name. */ __( 'Field `%s` must be an array of role slugs.', 'jetpack-stats-pkg' ), $role_field ) ); } // Direct PHP callers skip the REST schema's `minItems` check. if ( 'roles' === $role_field && empty( $provided[ $role_field ] ) ) { return new WP_Error( self::ERROR_PREFIX . 'invalid_roles', __( 'Field `roles` must be a non-empty array of role slugs.', 'jetpack-stats-pkg' ) ); } $sanitized = array(); foreach ( $provided[ $role_field ] as $role ) { if ( ! is_string( $role ) || '' === $role ) { return new WP_Error( self::ERROR_PREFIX . 'invalid_role', sprintf( /* translators: 1: field name, 2: comma-separated list of valid role slugs. */ __( 'Role slugs in `%1$s` must be non-empty strings. Known roles: %2$s.', 'jetpack-stats-pkg' ), $role_field, implode( ', ', $known_roles ) ) ); } if ( ! in_array( $role, $known_roles, true ) && ! in_array( $role, $before[ $role_field ], true ) ) { return new WP_Error( self::ERROR_PREFIX . 'invalid_role', sprintf( /* translators: 1: unknown role slug, 2: field name, 3: comma-separated list of valid role slugs. */ __( 'Unknown role `%1$s` in `%2$s`. Known roles: %3$s.', 'jetpack-stats-pkg' ), $role, $role_field, implode( ', ', $known_roles ) ) ); } $sanitized[] = $role; } // Administrators keep `view_stats`, because the screen that changes this list needs it. if ( 'roles' === $role_field && ! in_array( 'administrator', $sanitized, true ) ) { array_unshift( $sanitized, 'administrator' ); } $provided[ $role_field ] = array_values( array_unique( $sanitized ) ); } $changes = array(); foreach ( $provided as $key => $value ) { if ( is_bool( $defaults[ $key ] ?? null ) ) { $value = (bool) $value; } $current = $before[ $key ] ?? null; if ( $current === $value ) { continue; } $changes[ $key ] = $value; } if ( ! empty( $changes ) ) { Options::set_options( $changes ); } $after = self::get( $keys ); foreach ( $changes as $key => $value ) { if ( $after[ $key ] !== $value ) { return new WP_Error( self::ERROR_PREFIX . 'save_failed', __( 'The Stats settings could not be saved.', 'jetpack-stats-pkg' ) ); } } return array( 'changed' => $after !== $before, 'settings' => $after, ); } }