Changeset 3482605
- Timestamp:
- 03/14/2026 03:33:55 PM (2 weeks ago)
- Location:
- mode7-game-log
- Files:
-
- 28 edited
- 1 copied
-
tags/1.0.5 (copied) (copied from mode7-game-log/trunk)
-
tags/1.0.5/assets/css/admin.css (modified) (5 diffs)
-
tags/1.0.5/assets/js/admin.js (modified) (4 diffs)
-
tags/1.0.5/includes/class-game-log-admin.php (modified) (9 diffs)
-
tags/1.0.5/includes/class-game-log-ajax-handler.php (modified) (1 diff)
-
tags/1.0.5/includes/class-game-log-default-page.php (modified) (1 diff)
-
tags/1.0.5/includes/class-game-log-igdb-api.php (modified) (1 diff)
-
tags/1.0.5/includes/class-game-log-meta-fields.php (modified) (1 diff)
-
tags/1.0.5/includes/class-game-log-patterns.php (modified) (1 diff)
-
tags/1.0.5/includes/class-game-log-post-type.php (modified) (1 diff)
-
tags/1.0.5/includes/class-game-log-stats-block.php (modified) (1 diff)
-
tags/1.0.5/includes/class-game-log-taxonomy.php (modified) (1 diff)
-
tags/1.0.5/includes/class-game-log.php (modified) (2 diffs)
-
tags/1.0.5/mode7-game-log.php (modified) (2 diffs)
-
tags/1.0.5/readme.txt (modified) (2 diffs)
-
trunk/assets/css/admin.css (modified) (5 diffs)
-
trunk/assets/js/admin.js (modified) (4 diffs)
-
trunk/includes/class-game-log-admin.php (modified) (9 diffs)
-
trunk/includes/class-game-log-ajax-handler.php (modified) (1 diff)
-
trunk/includes/class-game-log-default-page.php (modified) (1 diff)
-
trunk/includes/class-game-log-igdb-api.php (modified) (1 diff)
-
trunk/includes/class-game-log-meta-fields.php (modified) (1 diff)
-
trunk/includes/class-game-log-patterns.php (modified) (1 diff)
-
trunk/includes/class-game-log-post-type.php (modified) (1 diff)
-
trunk/includes/class-game-log-stats-block.php (modified) (1 diff)
-
trunk/includes/class-game-log-taxonomy.php (modified) (1 diff)
-
trunk/includes/class-game-log.php (modified) (2 diffs)
-
trunk/mode7-game-log.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
mode7-game-log/tags/1.0.5/assets/css/admin.css
r3406333 r3482605 39 39 /* Game Filters */ 40 40 .game-filters { 41 display: flex; 41 42 background: #f1f1f1; 42 43 border-radius: 4px; 44 gap: 10px; 45 } 46 47 .game-filters input[type="text"] { 48 min-width: 200px; 43 49 } 44 50 45 51 /* Game Log List */ 52 53 .game-log-list { 54 margin-block-start: 10px; 55 } 46 56 47 57 .game-log-list th { … … 56 66 /* Game Search Modal */ 57 67 68 #game-search-modal::backdrop { 69 -webkit-backdrop-filter: blur(4px); 70 backdrop-filter: blur(4px); 71 background: rgba(0, 0, 0, 0.25); 72 } 73 58 74 .game-search-modal { 59 display: flex; 60 align-items: center; 61 justify-content: center; 75 background-color: #fff; 62 76 border-color: #eee; 63 77 border-radius: 4px; 64 78 box-shadow: 0 4px 6px rgba(0,0,0,0.1); 65 padding: 0;66 margin: 0;67 background-color: #fff;68 79 margin: auto; 69 80 padding: 0; … … 104 115 max-height: 60vh; 105 116 overflow-y: auto; 117 } 118 119 .game-search-modal-notice { 120 display: none; 121 margin-bottom: 15px; 122 } 123 124 .game-search-modal-notice.notice-error, 125 .game-search-modal-notice.notice-success { 126 display: block; 127 } 128 129 .game-search-modal-notice.notice-success { 130 border-left-color: #00a32a; 106 131 } 107 132 … … 381 406 } 382 407 408 ul.page-numbers { 409 display: flex; 410 gap: 10px 411 } 412 413 .page-numbers .current { 414 display: inline-block; 415 text-decoration: none; 416 font-size: 13px; 417 line-height: 2.15384615; 418 min-height: 30px; 419 margin: 0; 420 padding: 0 10px; 421 cursor: pointer; 422 border-width: 1px; 423 border-style: solid; 424 -webkit-appearance: none; 425 border-radius: 3px; 426 white-space: nowrap; 427 box-sizing: border-box; 428 } 429 383 430 /* Responsive Design */ 384 431 @media (max-width: 768px) { … … 403 450 flex-direction: column; 404 451 } 405 } 452 .game-filters { 453 flex-direction: column; 454 } 455 456 .game-filters input[type="text"], .game-filters select, .game-search-form input { 457 min-width: 100%; 458 } 459 } 460 461 @media (max-width: 782px) { 462 .page-numbers .current { 463 padding: 0 14px; 464 line-height: 2.71428571; 465 font-size: 14px; 466 } 467 } -
mode7-game-log/tags/1.0.5/assets/js/admin.js
r3406333 r3482605 39 39 const modal = document.getElementById('game-search-modal'); 40 40 if (modal) { 41 modal.s tyle.display = 'block';41 modal.showModal(); 42 42 } 43 43 if (searchInput) { … … 83 83 function closeModal() { 84 84 if (modal) { 85 modal. style.display = 'none';85 modal.close(); 86 86 } 87 87 const searchInput = document.getElementById('game-search-input'); … … 369 369 } 370 370 371 // Show success message 372 showNotice('success', gameLogAjax.strings.gameAdded); 373 374 // Refresh the page after a short delay to show the success state 375 setTimeout(function() { 376 window.location.reload(); 377 }, 1500); 371 // Show success message in modal or on page 372 if (button.closest('#game-search-modal')) { 373 showNoticeInModal(gameLogAjax.strings.gameAdded, 'success'); 374 // Redirect to default games list so the new game appears in the list 375 setTimeout(function() { 376 window.location.href = gameLogAjax.gamesListUrl; 377 }, 1500); 378 } else { 379 showNotice('success', gameLogAjax.strings.gameAdded); 380 setTimeout(function() { 381 window.location.reload(); 382 }, 1500); 383 } 378 384 } else { 379 385 button.disabled = false; 380 386 button.textContent = 'Add Game'; 381 showNotice('error', data.data.message || gameLogAjax.strings.error); 387 const msg = data.data && data.data.message ? data.data.message : gameLogAjax.strings.error; 388 if (button.closest('#game-search-modal')) { 389 showNoticeInModal(msg); 390 } else { 391 showNotice('error', msg); 392 } 382 393 } 383 394 }) … … 386 397 button.disabled = false; 387 398 button.textContent = 'Add Game'; 388 showNotice('error', gameLogAjax.strings.error); 389 }); 399 const msg = gameLogAjax.strings.error; 400 if (button.closest('#game-search-modal')) { 401 showNoticeInModal(msg); 402 } else { 403 showNotice('error', msg); 404 } 405 }); 406 } 407 408 /** 409 * Show notice inside the game search modal 410 * @param {string} message - Message text 411 * @param {string} type - 'success' or 'error' (default 'error') 412 */ 413 function showNoticeInModal(message, type) { 414 const container = document.getElementById('game-search-modal-notice'); 415 if (!container) return; 416 type = type || 'error'; 417 const noticeClass = type === 'success' ? 'notice-success' : 'notice-error'; 418 container.innerHTML = '<p>' + message + '</p>'; 419 container.className = 'game-search-modal-notice notice ' + noticeClass + ' is-dismissible'; 420 container.style.display = ''; 421 422 setTimeout(function() { 423 container.style.opacity = '0'; 424 container.style.transition = 'opacity 0.5s ease-out'; 425 setTimeout(function() { 426 container.innerHTML = ''; 427 container.className = 'game-search-modal-notice'; 428 container.style.display = 'none'; 429 container.style.opacity = ''; 430 }, 500); 431 }, 5000); 390 432 } 391 433 -
mode7-game-log/tags/1.0.5/includes/class-game-log-admin.php
r3406333 r3482605 10 10 * @since 1.0.0 11 11 */ 12 13 // Prevent direct access. 14 if ( ! defined( 'ABSPATH' ) ) { 15 exit; 16 } 12 17 13 18 /** … … 258 263 259 264 <!-- Game Search Modal --> 260 <dialog id="game-search-modal" class="game-search-modal" style="display: none;">265 <dialog id="game-search-modal" class="game-search-modal"> 261 266 262 267 <div class="game-search-modal-header"> … … 265 270 </div> 266 271 <div class="game-search-modal-body"> 272 <div id="game-search-modal-notice" class="game-search-modal-notice" role="alert" aria-live="polite"></div> 267 273 <p><?php esc_html_e( 'Search the Internet Gaming Database for to add a game to your log.', 'mode7-game-log' ); ?></p> 268 274 <div class="game-search-form"> … … 340 346 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 341 347 $current_status = isset( $_GET['game_status'] ) ? sanitize_text_field( wp_unslash( $_GET['game_status'] ) ) : ''; 348 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 349 $current_search = isset( $_GET['s'] ) && is_string( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; 342 350 343 351 ?> 344 352 <form method="get" class="game-filters"> 345 353 <input type="hidden" name="page" value="mode7-game-log" /> 354 <label for="game-log-search-input" class="screen-reader-text"><?php esc_html_e( 'Search games', 'mode7-game-log' ); ?></label> 355 <input type="text" name="s" id="game-log-search-input" value="<?php echo esc_attr( $current_search ); ?>" placeholder="<?php esc_attr_e( 'Search by title…', 'mode7-game-log' ); ?>" class="regular-text" /> 346 356 <select name="game_status" id="game_status_filter"> 347 357 <option value=""><?php esc_html_e( 'All Statuses', 'mode7-game-log' ); ?></option> … … 361 371 */ 362 372 private function display_games_list(): void { 373 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only pagination, no data modification 374 $current_page = isset( $_GET['paged'] ) ? max( 1, absint( $_GET['paged'] ) ) : 1; 375 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 376 $current_status = isset( $_GET['game_status'] ) && is_string( $_GET['game_status'] ) ? sanitize_text_field( wp_unslash( $_GET['game_status'] ) ) : ''; 377 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 378 $current_search = isset( $_GET['s'] ) && is_string( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; 379 363 380 $args = array( 364 381 'post_type' => 'game', 365 382 'post_status' => 'publish', 366 383 'posts_per_page' => 20, 367 'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1, 368 ); 384 'paged' => $current_page, 385 ); 386 387 if ( ! empty( $current_search ) ) { 388 $args['s'] = $current_search; 389 } 369 390 370 391 // Add status filter if selected. 371 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 372 if ( isset( $_GET['game_status'] ) && ! empty( $_GET['game_status'] ) ) { 392 if ( ! empty( $current_status ) ) { 373 393 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Required for filtering games by status 374 394 $args['tax_query'] = array( … … 376 396 'taxonomy' => 'game_status', 377 397 'field' => 'slug', 378 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 379 'terms' => sanitize_text_field( wp_unslash( $_GET['game_status'] ) ), 398 'terms' => $current_status, 380 399 ), 381 400 ); … … 465 484 <?php 466 485 // Pagination. 486 $base = add_query_arg( 'page', 'mode7-game-log', admin_url( 'admin.php' ) ); 487 if ( ! empty( $current_status ) ) { 488 $base = add_query_arg( 'game_status', $current_status, $base ); 489 } 490 if ( ! empty( $current_search ) ) { 491 $base = add_query_arg( 's', $current_search, $base ); 492 } 467 493 $pagination_args = array( 468 494 'total' => $games->max_num_pages, 469 'current' => max( 1, get_query_var( 'paged' ) ), 470 'format' => '?paged=%#%', 495 'current' => $current_page, 496 'base' => $base . '&paged=%#%', 497 'format' => '', 471 498 'show_all' => false, 472 499 'type' => 'list', … … 480 507 ); 481 508 509 $pagination_links = paginate_links( $pagination_args ); 510 if ( $pagination_links ) { 511 $pagination_links = str_replace( ' class="next page-numbers"', ' class="button next page-numbers"', $pagination_links ); 512 $pagination_links = str_replace( ' class="prev page-numbers"', ' class="button prev page-numbers"', $pagination_links ); 513 $pagination_links = str_replace( '<a class="page-numbers"', '<a class="button page-numbers"', $pagination_links ); 514 } 482 515 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 483 echo paginate_links( $pagination_args );516 echo $pagination_links; 484 517 ?> 485 518 … … 487 520 } else { 488 521 ?> 489 <p><?php e sc_html_e( 'No games found.', 'mode7-game-log' ); ?></p>522 <p><?php echo ! empty( $current_search ) ? esc_html__( 'No games match your search.', 'mode7-game-log' ) : esc_html__( 'No games found.', 'mode7-game-log' ); ?></p> 490 523 <?php 491 524 } -
mode7-game-log/tags/1.0.5/includes/class-game-log-ajax-handler.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/tags/1.0.5/includes/class-game-log-default-page.php
r3406333 r3482605 11 11 */ 12 12 13 declare(strict_types=1); 13 // Prevent direct access. 14 if ( ! defined( 'ABSPATH' ) ) { 15 exit; 16 } 14 17 15 18 /** -
mode7-game-log/tags/1.0.5/includes/class-game-log-igdb-api.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/tags/1.0.5/includes/class-game-log-meta-fields.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/tags/1.0.5/includes/class-game-log-patterns.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/tags/1.0.5/includes/class-game-log-post-type.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/tags/1.0.5/includes/class-game-log-stats-block.php
r3406333 r3482605 11 11 */ 12 12 13 declare(strict_types=1); 13 // Prevent direct access. 14 if ( ! defined( 'ABSPATH' ) ) { 15 exit; 16 } 14 17 15 18 /** -
mode7-game-log/tags/1.0.5/includes/class-game-log-taxonomy.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/tags/1.0.5/includes/class-game-log.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** … … 67 70 'gameLogAjax', 68 71 array( 69 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 70 'nonce' => wp_create_nonce( 'game_log_nonce' ), 72 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 73 'gamesListUrl' => add_query_arg( 'page', 'mode7-game-log', admin_url( 'admin.php' ) ), 74 'nonce' => wp_create_nonce( 'game_log_nonce' ), 71 75 'strings' => array( 72 76 'searching' => __( 'Searching...', 'mode7-game-log' ), -
mode7-game-log/tags/1.0.5/mode7-game-log.php
r3406333 r3482605 4 4 * Plugin URI: https://www.bobmatyas.com 5 5 * Description: A WordPress plugin to track video games you've played, are playing, or want to play using IGDB.com database. 6 * Version: 1.0. 46 * Version: 1.0.5 7 7 * Author: Bob Matyas 8 8 * License: GPL v2 or later … … 18 18 19 19 // Define plugin constants. 20 define( 'GAME_LOG_VERSION', '1.0. 4' );20 define( 'GAME_LOG_VERSION', '1.0.5' ); 21 21 define( 'GAME_LOG_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 22 22 define( 'GAME_LOG_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
mode7-game-log/tags/1.0.5/readme.txt
r3406333 r3482605 5 5 Tested up to: 6.9 6 6 Requires PHP: 8.2 7 Stable tag: 1.0. 47 Stable tag: 1.0.5 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 91 91 == Changelog == 92 92 93 = 1.0.5 = 94 95 * Fix pagination. 96 * Move error notice to inside modal. 97 * Add modal backdrop. 98 * Add search filter. 99 * Add direct file access check. 100 * Refresh admin page when adding game. 101 * Update mobile and pagination styles. 102 93 103 = 1.0.4 = 94 104 -
mode7-game-log/trunk/assets/css/admin.css
r3406333 r3482605 39 39 /* Game Filters */ 40 40 .game-filters { 41 display: flex; 41 42 background: #f1f1f1; 42 43 border-radius: 4px; 44 gap: 10px; 45 } 46 47 .game-filters input[type="text"] { 48 min-width: 200px; 43 49 } 44 50 45 51 /* Game Log List */ 52 53 .game-log-list { 54 margin-block-start: 10px; 55 } 46 56 47 57 .game-log-list th { … … 56 66 /* Game Search Modal */ 57 67 68 #game-search-modal::backdrop { 69 -webkit-backdrop-filter: blur(4px); 70 backdrop-filter: blur(4px); 71 background: rgba(0, 0, 0, 0.25); 72 } 73 58 74 .game-search-modal { 59 display: flex; 60 align-items: center; 61 justify-content: center; 75 background-color: #fff; 62 76 border-color: #eee; 63 77 border-radius: 4px; 64 78 box-shadow: 0 4px 6px rgba(0,0,0,0.1); 65 padding: 0;66 margin: 0;67 background-color: #fff;68 79 margin: auto; 69 80 padding: 0; … … 104 115 max-height: 60vh; 105 116 overflow-y: auto; 117 } 118 119 .game-search-modal-notice { 120 display: none; 121 margin-bottom: 15px; 122 } 123 124 .game-search-modal-notice.notice-error, 125 .game-search-modal-notice.notice-success { 126 display: block; 127 } 128 129 .game-search-modal-notice.notice-success { 130 border-left-color: #00a32a; 106 131 } 107 132 … … 381 406 } 382 407 408 ul.page-numbers { 409 display: flex; 410 gap: 10px 411 } 412 413 .page-numbers .current { 414 display: inline-block; 415 text-decoration: none; 416 font-size: 13px; 417 line-height: 2.15384615; 418 min-height: 30px; 419 margin: 0; 420 padding: 0 10px; 421 cursor: pointer; 422 border-width: 1px; 423 border-style: solid; 424 -webkit-appearance: none; 425 border-radius: 3px; 426 white-space: nowrap; 427 box-sizing: border-box; 428 } 429 383 430 /* Responsive Design */ 384 431 @media (max-width: 768px) { … … 403 450 flex-direction: column; 404 451 } 405 } 452 .game-filters { 453 flex-direction: column; 454 } 455 456 .game-filters input[type="text"], .game-filters select, .game-search-form input { 457 min-width: 100%; 458 } 459 } 460 461 @media (max-width: 782px) { 462 .page-numbers .current { 463 padding: 0 14px; 464 line-height: 2.71428571; 465 font-size: 14px; 466 } 467 } -
mode7-game-log/trunk/assets/js/admin.js
r3406333 r3482605 39 39 const modal = document.getElementById('game-search-modal'); 40 40 if (modal) { 41 modal.s tyle.display = 'block';41 modal.showModal(); 42 42 } 43 43 if (searchInput) { … … 83 83 function closeModal() { 84 84 if (modal) { 85 modal. style.display = 'none';85 modal.close(); 86 86 } 87 87 const searchInput = document.getElementById('game-search-input'); … … 369 369 } 370 370 371 // Show success message 372 showNotice('success', gameLogAjax.strings.gameAdded); 373 374 // Refresh the page after a short delay to show the success state 375 setTimeout(function() { 376 window.location.reload(); 377 }, 1500); 371 // Show success message in modal or on page 372 if (button.closest('#game-search-modal')) { 373 showNoticeInModal(gameLogAjax.strings.gameAdded, 'success'); 374 // Redirect to default games list so the new game appears in the list 375 setTimeout(function() { 376 window.location.href = gameLogAjax.gamesListUrl; 377 }, 1500); 378 } else { 379 showNotice('success', gameLogAjax.strings.gameAdded); 380 setTimeout(function() { 381 window.location.reload(); 382 }, 1500); 383 } 378 384 } else { 379 385 button.disabled = false; 380 386 button.textContent = 'Add Game'; 381 showNotice('error', data.data.message || gameLogAjax.strings.error); 387 const msg = data.data && data.data.message ? data.data.message : gameLogAjax.strings.error; 388 if (button.closest('#game-search-modal')) { 389 showNoticeInModal(msg); 390 } else { 391 showNotice('error', msg); 392 } 382 393 } 383 394 }) … … 386 397 button.disabled = false; 387 398 button.textContent = 'Add Game'; 388 showNotice('error', gameLogAjax.strings.error); 389 }); 399 const msg = gameLogAjax.strings.error; 400 if (button.closest('#game-search-modal')) { 401 showNoticeInModal(msg); 402 } else { 403 showNotice('error', msg); 404 } 405 }); 406 } 407 408 /** 409 * Show notice inside the game search modal 410 * @param {string} message - Message text 411 * @param {string} type - 'success' or 'error' (default 'error') 412 */ 413 function showNoticeInModal(message, type) { 414 const container = document.getElementById('game-search-modal-notice'); 415 if (!container) return; 416 type = type || 'error'; 417 const noticeClass = type === 'success' ? 'notice-success' : 'notice-error'; 418 container.innerHTML = '<p>' + message + '</p>'; 419 container.className = 'game-search-modal-notice notice ' + noticeClass + ' is-dismissible'; 420 container.style.display = ''; 421 422 setTimeout(function() { 423 container.style.opacity = '0'; 424 container.style.transition = 'opacity 0.5s ease-out'; 425 setTimeout(function() { 426 container.innerHTML = ''; 427 container.className = 'game-search-modal-notice'; 428 container.style.display = 'none'; 429 container.style.opacity = ''; 430 }, 500); 431 }, 5000); 390 432 } 391 433 -
mode7-game-log/trunk/includes/class-game-log-admin.php
r3406333 r3482605 10 10 * @since 1.0.0 11 11 */ 12 13 // Prevent direct access. 14 if ( ! defined( 'ABSPATH' ) ) { 15 exit; 16 } 12 17 13 18 /** … … 258 263 259 264 <!-- Game Search Modal --> 260 <dialog id="game-search-modal" class="game-search-modal" style="display: none;">265 <dialog id="game-search-modal" class="game-search-modal"> 261 266 262 267 <div class="game-search-modal-header"> … … 265 270 </div> 266 271 <div class="game-search-modal-body"> 272 <div id="game-search-modal-notice" class="game-search-modal-notice" role="alert" aria-live="polite"></div> 267 273 <p><?php esc_html_e( 'Search the Internet Gaming Database for to add a game to your log.', 'mode7-game-log' ); ?></p> 268 274 <div class="game-search-form"> … … 340 346 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 341 347 $current_status = isset( $_GET['game_status'] ) ? sanitize_text_field( wp_unslash( $_GET['game_status'] ) ) : ''; 348 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 349 $current_search = isset( $_GET['s'] ) && is_string( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; 342 350 343 351 ?> 344 352 <form method="get" class="game-filters"> 345 353 <input type="hidden" name="page" value="mode7-game-log" /> 354 <label for="game-log-search-input" class="screen-reader-text"><?php esc_html_e( 'Search games', 'mode7-game-log' ); ?></label> 355 <input type="text" name="s" id="game-log-search-input" value="<?php echo esc_attr( $current_search ); ?>" placeholder="<?php esc_attr_e( 'Search by title…', 'mode7-game-log' ); ?>" class="regular-text" /> 346 356 <select name="game_status" id="game_status_filter"> 347 357 <option value=""><?php esc_html_e( 'All Statuses', 'mode7-game-log' ); ?></option> … … 361 371 */ 362 372 private function display_games_list(): void { 373 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only pagination, no data modification 374 $current_page = isset( $_GET['paged'] ) ? max( 1, absint( $_GET['paged'] ) ) : 1; 375 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 376 $current_status = isset( $_GET['game_status'] ) && is_string( $_GET['game_status'] ) ? sanitize_text_field( wp_unslash( $_GET['game_status'] ) ) : ''; 377 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 378 $current_search = isset( $_GET['s'] ) && is_string( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; 379 363 380 $args = array( 364 381 'post_type' => 'game', 365 382 'post_status' => 'publish', 366 383 'posts_per_page' => 20, 367 'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1, 368 ); 384 'paged' => $current_page, 385 ); 386 387 if ( ! empty( $current_search ) ) { 388 $args['s'] = $current_search; 389 } 369 390 370 391 // Add status filter if selected. 371 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 372 if ( isset( $_GET['game_status'] ) && ! empty( $_GET['game_status'] ) ) { 392 if ( ! empty( $current_status ) ) { 373 393 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Required for filtering games by status 374 394 $args['tax_query'] = array( … … 376 396 'taxonomy' => 'game_status', 377 397 'field' => 'slug', 378 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET form for filtering, no data modification 379 'terms' => sanitize_text_field( wp_unslash( $_GET['game_status'] ) ), 398 'terms' => $current_status, 380 399 ), 381 400 ); … … 465 484 <?php 466 485 // Pagination. 486 $base = add_query_arg( 'page', 'mode7-game-log', admin_url( 'admin.php' ) ); 487 if ( ! empty( $current_status ) ) { 488 $base = add_query_arg( 'game_status', $current_status, $base ); 489 } 490 if ( ! empty( $current_search ) ) { 491 $base = add_query_arg( 's', $current_search, $base ); 492 } 467 493 $pagination_args = array( 468 494 'total' => $games->max_num_pages, 469 'current' => max( 1, get_query_var( 'paged' ) ), 470 'format' => '?paged=%#%', 495 'current' => $current_page, 496 'base' => $base . '&paged=%#%', 497 'format' => '', 471 498 'show_all' => false, 472 499 'type' => 'list', … … 480 507 ); 481 508 509 $pagination_links = paginate_links( $pagination_args ); 510 if ( $pagination_links ) { 511 $pagination_links = str_replace( ' class="next page-numbers"', ' class="button next page-numbers"', $pagination_links ); 512 $pagination_links = str_replace( ' class="prev page-numbers"', ' class="button prev page-numbers"', $pagination_links ); 513 $pagination_links = str_replace( '<a class="page-numbers"', '<a class="button page-numbers"', $pagination_links ); 514 } 482 515 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 483 echo paginate_links( $pagination_args );516 echo $pagination_links; 484 517 ?> 485 518 … … 487 520 } else { 488 521 ?> 489 <p><?php e sc_html_e( 'No games found.', 'mode7-game-log' ); ?></p>522 <p><?php echo ! empty( $current_search ) ? esc_html__( 'No games match your search.', 'mode7-game-log' ) : esc_html__( 'No games found.', 'mode7-game-log' ); ?></p> 490 523 <?php 491 524 } -
mode7-game-log/trunk/includes/class-game-log-ajax-handler.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/trunk/includes/class-game-log-default-page.php
r3406333 r3482605 11 11 */ 12 12 13 declare(strict_types=1); 13 // Prevent direct access. 14 if ( ! defined( 'ABSPATH' ) ) { 15 exit; 16 } 14 17 15 18 /** -
mode7-game-log/trunk/includes/class-game-log-igdb-api.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/trunk/includes/class-game-log-meta-fields.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/trunk/includes/class-game-log-patterns.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/trunk/includes/class-game-log-post-type.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/trunk/includes/class-game-log-stats-block.php
r3406333 r3482605 11 11 */ 12 12 13 declare(strict_types=1); 13 // Prevent direct access. 14 if ( ! defined( 'ABSPATH' ) ) { 15 exit; 16 } 14 17 15 18 /** -
mode7-game-log/trunk/includes/class-game-log-taxonomy.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** -
mode7-game-log/trunk/includes/class-game-log.php
r3406333 r3482605 7 7 */ 8 8 9 declare(strict_types=1); 9 // Prevent direct access. 10 if ( ! defined( 'ABSPATH' ) ) { 11 exit; 12 } 10 13 11 14 /** … … 67 70 'gameLogAjax', 68 71 array( 69 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 70 'nonce' => wp_create_nonce( 'game_log_nonce' ), 72 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 73 'gamesListUrl' => add_query_arg( 'page', 'mode7-game-log', admin_url( 'admin.php' ) ), 74 'nonce' => wp_create_nonce( 'game_log_nonce' ), 71 75 'strings' => array( 72 76 'searching' => __( 'Searching...', 'mode7-game-log' ), -
mode7-game-log/trunk/mode7-game-log.php
r3406333 r3482605 4 4 * Plugin URI: https://www.bobmatyas.com 5 5 * Description: A WordPress plugin to track video games you've played, are playing, or want to play using IGDB.com database. 6 * Version: 1.0. 46 * Version: 1.0.5 7 7 * Author: Bob Matyas 8 8 * License: GPL v2 or later … … 18 18 19 19 // Define plugin constants. 20 define( 'GAME_LOG_VERSION', '1.0. 4' );20 define( 'GAME_LOG_VERSION', '1.0.5' ); 21 21 define( 'GAME_LOG_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 22 22 define( 'GAME_LOG_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
mode7-game-log/trunk/readme.txt
r3406333 r3482605 5 5 Tested up to: 6.9 6 6 Requires PHP: 8.2 7 Stable tag: 1.0. 47 Stable tag: 1.0.5 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 91 91 == Changelog == 92 92 93 = 1.0.5 = 94 95 * Fix pagination. 96 * Move error notice to inside modal. 97 * Add modal backdrop. 98 * Add search filter. 99 * Add direct file access check. 100 * Refresh admin page when adding game. 101 * Update mobile and pagination styles. 102 93 103 = 1.0.4 = 94 104
Note: See TracChangeset
for help on using the changeset viewer.