$payload Profile configuration. * @return array The saved profile item. */ public static function save( string $name, string $type, array $payload ): array { $profiles = self::get_saved(); $id = wp_generate_uuid4(); $item = array( 'id' => $id, 'name' => sanitize_text_field( $name ), 'type' => sanitize_key( $type ), 'payload' => $payload, 'created_at' => time(), 'updated_at' => time(), ); $profiles[] = $item; update_option( 'spinxqm_profiles_saved', $profiles, false ); return $item; } /** * Overwrite an existing profile's type + payload with the current configuration. * Keeps created_at; bumps updated_at. When $name is a non-empty string the profile is * also renamed (caller is responsible for the duplicate-name check). Returns the updated * item, or null if no profile matched the id. * * @param string $id Profile ID. * @param string $type Profile type. * @param array $payload Profile configuration. * @param string|null $name Optional new name. * @return array|null */ public static function update( string $id, string $type, array $payload, ?string $name = null ): ?array { $profiles = self::get_saved(); $updated = null; foreach ( $profiles as &$profile ) { if ( isset( $profile['id'] ) && $profile['id'] === $id ) { $profile['type'] = sanitize_key( $type ); $profile['payload'] = $payload; if ( null !== $name && '' !== trim( $name ) ) { $profile['name'] = sanitize_text_field( $name ); } $profile['updated_at'] = time(); $updated = $profile; break; } } unset( $profile ); if ( null !== $updated ) { update_option( 'spinxqm_profiles_saved', $profiles, false ); } return $updated; } /** * Rename profile. * * @param string $id Profile ID. * @param string $name New profile name. * @return bool Whether a profile was renamed. */ public static function rename( string $id, string $name ): bool { $profiles = self::get_saved(); $changed = false; foreach ( $profiles as &$profile ) { if ( isset( $profile['id'] ) && $profile['id'] === $id ) { $profile['name'] = sanitize_text_field( $name ); $profile['updated_at'] = time(); $changed = true; break; } } if ( $changed ) { update_option( 'spinxqm_profiles_saved', $profiles, false ); } return $changed; } /** * Delete profile. * * @param string $id Profile ID. * @return bool Whether a profile was deleted. */ public static function delete( string $id ): bool { $profiles = self::get_saved(); $before = count( $profiles ); $profiles = array_values( array_filter( $profiles, static function ( $item ) use ( $id ) { return ! isset( $item['id'] ) || $item['id'] !== $id; } ) ); if ( count( $profiles ) !== $before ) { update_option( 'spinxqm_profiles_saved', $profiles, false ); return true; } return false; } /** * Save recent unsaved profile. * * @param string $label Display label. * @param string $type Profile type. * @param array $payload Profile configuration. * @return array The stored recent item. */ public static function save_recent( string $label, string $type, array $payload ): array { $settings = Helpers::get_settings(); $max = max( 1, absint( $settings['max_recent_unsaved'] ) ); $recent = self::get_recent(); $item = array( 'id' => wp_generate_uuid4(), 'label' => sanitize_text_field( $label ), 'type' => sanitize_key( $type ), 'payload' => $payload, 'created_at' => time(), ); array_unshift( $recent, $item ); $recent = array_slice( $recent, 0, $max ); update_option( 'spinxqm_profiles_recent', $recent, false ); return $item; } /** * Delete a recent unsaved profile by id. * * @param string $id Recent profile ID. * @return bool Whether a recent profile was deleted. */ public static function delete_recent( string $id ): bool { $recent = self::get_recent(); $before = count( $recent ); $recent = array_values( array_filter( $recent, static function ( $item ) use ( $id ) { return ! isset( $item['id'] ) || $item['id'] !== $id; } ) ); if ( count( $recent ) !== $before ) { update_option( 'spinxqm_profiles_recent', $recent, false ); return true; } return false; } }