scrobbles_table = 'song_scrobbles'; // Added $wpdb->prefix for table names $this->scores_table = 'album_scores'; // Add admin menu add_action( 'admin_menu', array( $this, 'add_admin_menu' ) ); // Enqueue admin scripts add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); // Add AJAX handler add_action( 'wp_ajax_asm_update_score', array( $this, 'ajax_update_score' ) ); } /** * Enqueue custom JavaScript for handling AJAX requests */ public function enqueue_admin_scripts( $hook ) { // Only enqueue on our plugin's admin page if ( $hook !== 'toplevel_page_album-score-manager' ) { return; } // Enqueue the script wp_enqueue_script( 'asm-admin-script', plugin_dir_url( __FILE__ ) . 'js/asm-admin.js', // You'll create this file next array( 'jquery' ), '1.1', true ); // Localize script to pass AJAX URL and nonce wp_localize_script( 'asm-admin-script', 'asm_ajax_obj', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'asm_ajax_nonce' ), ) ); } /** * Add a new menu item under the WordPress admin sidebar */ public function add_admin_menu() { add_menu_page( 'Album Score Manager', // Page title 'Album Scores', // Menu title 'manage_options', // Capability 'album-score-manager', // Menu slug array( $this, 'admin_page' ), // Callback function 'dashicons-awards', // Icon 6 // Position ); } /** * Admin page callback */ public function admin_page() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); } global $wpdb; // Fetch albums sorted by total plays $albums = $wpdb->get_results( "SELECT album_name, COUNT(*) as play_count FROM `{$this->scrobbles_table}` WHERE album_name IS NOT NULL GROUP BY album_name ORDER BY play_count DESC", OBJECT ); // Fetch existing scores $existing_scores = $wpdb->get_results( "SELECT album_name, score, author, cover_url FROM `{$this->scores_table}`", ARRAY_A ); $scores_assoc = array(); foreach ( $existing_scores as $score ) { $scores_assoc[ $score['album_name'] ] = array( 'score' => $score['score'], 'author' => $score['author'], 'cover_url' => $score['cover_url'], ); } // Prepare latest author and cover_url from song_scrobbles $latest_entries = $this->get_latest_song_scrobbles( $albums ); ?>

Album Score Manager

album_name ); $play_count = intval( $album->play_count ); // Fetch latest song_scrobbles entry for this album $latest_entry = isset( $latest_entries[ $album->album_name ] ) ? $latest_entries[ $album->album_name ] : null; $latest_author = $latest_entry ? esc_html( $latest_entry->author ) : ''; $latest_cover_url = $latest_entry ? esc_url( $latest_entry->cover_url ) : ''; // Existing scores $current_score = isset( $scores_assoc[ $album->album_name ]['score'] ) ? esc_html( $scores_assoc[ $album->album_name ]['score'] ) : ''; $current_author = isset( $scores_assoc[ $album->album_name ]['author'] ) ? esc_html( $scores_assoc[ $album->album_name ]['author'] ) : $latest_author; $current_cover_url = isset( $scores_assoc[ $album->album_name ]['cover_url'] ) ? esc_url( $scores_assoc[ $album->album_name ]['cover_url'] ) : $latest_cover_url; ?>
Album Name Author Cover Total Plays Score Status
No albums found.
get_row( $wpdb->prepare( "SELECT author, cover_url FROM `{$this->scrobbles_table}` WHERE album_name = %s ORDER BY id DESC LIMIT 1", $album->album_name ) ); if ( $latest_entry ) { $latest_entries[ $album->album_name ] = $latest_entry; } } return $latest_entries; } /** * AJAX handler to update a single album's score */ public function ajax_update_score() { // Check nonce check_ajax_referer( 'asm_ajax_nonce', 'nonce' ); // Check user capabilities if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'Unauthorized user.' ); wp_die(); } // Get and sanitize input $album = isset( $_POST['album'] ) ? sanitize_text_field( $_POST['album'] ) : ''; $score = isset( $_POST['score'] ) ? sanitize_text_field( $_POST['score'] ) : ''; $cover_url = isset( $_POST['cover_url'] ) ? esc_url_raw( $_POST['cover_url'] ) : ''; $author = isset( $_POST['author'] ) ? sanitize_text_field( $_POST['author'] ) : ''; // Validate input $valid_scores = array( 'F', 'C', 'B', 'A', 'S', 'S+' ); if ( empty( $album ) || empty( $score ) || ! in_array( $score, $valid_scores, true ) ) { wp_send_json_error( 'Invalid input.' ); wp_die(); } global $wpdb; // Check if the album already has a score $existing = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM `{$this->scores_table}` WHERE `album_name` = %s", $album ) ); if ( $existing ) { // Update existing record $updated_rows = $wpdb->update( $this->scores_table, array( 'score' => $score, 'author' => $author, 'cover_url' => $cover_url, ), array( 'id' => $existing ), array( '%s', '%s', '%s' ), array( '%d' ) ); if ( false !== $updated_rows ) { wp_send_json_success( 'Score updated successfully.' ); } else { wp_send_json_error( 'Failed to update score.' ); } } else { // Insert new record $inserted_rows = $wpdb->insert( $this->scores_table, array( 'album_name' => $album, 'score' => $score, 'author' => $author, 'cover_url' => $cover_url, ), array( '%s', '%s', '%s', '%s' ) ); if ( false !== $inserted_rows ) { wp_send_json_success( 'Score added successfully.' ); } else { wp_send_json_error( 'Failed to add score.' ); } } wp_die(); } }