Changeset 3416922
- Timestamp:
- 12/11/2025 03:22:29 AM (2 months ago)
- Location:
- rscsoft-activity-audit-log/trunk
- Files:
-
- 2 added
- 2 edited
-
languages/rscsoft-activity-audit-log-ja.mo (added)
-
languages/rscsoft-activity-audit-log-ja.po (added)
-
readme.txt (modified) (2 diffs)
-
rscsoft-activity-audit-log.php (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
rscsoft-activity-audit-log/trunk/readme.txt
r3414225 r3416922 5 5 Requires at least: 6.0 6 6 Tested up to: 6.9 7 Stable tag: 1.2. 07 Stable tag: 1.2.1 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 71 71 == Changelog == 72 72 73 = 1.2.1 = 74 * Fixed: Log display issue where logs were not shown on the admin screen. 75 修正:管理画面でログが表示されない問題を修正。 76 * Added: Japanese translation support. 77 追加:日本語翻訳に対応。 78 73 79 = 1.2.0 = 74 * Initial public release: Activity logging, CSV export, retention setting, and automatic cleanup. 80 * Initial public release: Activity logging, CSV export, retention setting, and automatic cleanup. 75 81 初回公開バージョン:操作ログ記録、CSVエクスポート、保持日数設定、自動削除を実装。 76 82 77 83 == Upgrade Notice == 78 1.2.0 – First public release. 79 1.2.0 – 初回公開バージョン。 84 85 = 1.2.1 = 86 Bug fix for log display and Japanese translation support. 87 ログ表示のバグ修正と日本語翻訳対応。 88 89 = 1.2.0 = 90 First public release. 91 初回公開バージョン。 -
rscsoft-activity-audit-log/trunk/rscsoft-activity-audit-log.php
r3414225 r3416922 3 3 * Plugin Name: RSCSoft Activity Audit Log 4 4 * Description: Record user operations (posts/pages/plugins/themes/login/logout), filter logs, export CSV, set retention, and auto-clean via WP-Cron. 日本語: 投稿/固定ページ/プラグイン/テーマ/ログイン/ログアウトの操作を監査ログとして記録し、フィルタ・CSV出力・保持日数設定・自動削除に対応します。 5 * Version: 1.2. 05 * Version: 1.2.1 6 6 * Author: Masahiro Sakamoto 7 7 * Author URI: https://profiles.wordpress.org/rscsoft/ … … 38 38 39 39 /** 40 * Constructor. Registers hooks for a ctivation, admin menu,and event logging.40 * Constructor. Registers hooks for admin menu and event logging. 41 41 */ 42 42 public function __construct() { 43 register_activation_hook( __FILE__, array( $this, 'activate' ) );44 register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );45 46 43 add_action( 'admin_menu', array( $this, 'admin_menu' ) ); 47 44 add_action( 'admin_post_rscsoft_aal_export_csv', array( $this, 'export_csv' ) ); … … 124 121 * 有効化時:テーブル作成 + デフォルト保持日数 + Cron登録. 125 122 */ 126 public function activate() {123 public static function activate() { 127 124 global $wpdb; 128 125 … … 132 129 } 133 130 134 $table = $ this->table_name();131 $table = $wpdb->prefix . 'rscsoft_aal_log'; 135 132 $charset = $wpdb->get_charset_collate(); 136 133 … … 175 172 * Plugin deactivation handler. Unschedules the cleanup cron event. 176 173 */ 177 public function deactivate() {174 public static function deactivate() { 178 175 $timestamp = wp_next_scheduled( self::CRON_HOOK ); 179 176 if ( $timestamp ) { … … 452 449 public function admin_menu() { 453 450 add_menu_page( 454 'Activity Logs',455 'Activity Logs',451 esc_html__( 'Activity Logs', 'rscsoft-activity-audit-log' ), 452 esc_html__( 'Activity Logs', 'rscsoft-activity-audit-log' ), 456 453 'manage_options', 457 454 'rscsoft-activity-audit-log', … … 462 459 add_submenu_page( 463 460 'rscsoft-activity-audit-log', 464 'Settings',465 'Settings',461 esc_html__( 'Settings', 'rscsoft-activity-audit-log' ), 462 esc_html__( 'Settings', 'rscsoft-activity-audit-log' ), 466 463 'manage_options', 467 464 'rscsoft-activity-audit-log-settings', … … 508 505 $action_options = $wpdb->get_col( "SELECT DISTINCT action FROM {$table_esc} ORDER BY action ASC" ); 509 506 510 /* 511 * Build query with all conditions using NULL coalesce pattern. 512 * すべての条件を含むクエリを構築。空の場合はNULLとして扱い、条件をスキップします。 513 */ 514 $user_param = ( '' !== $user ) ? $user : null; 515 $action_param = ( '' !== $action_k ) ? $action_k : null; 516 $date_from_param = ( '' !== $date_from ) ? $date_from . ' 00:00:00' : null; 517 $date_to_param = ( '' !== $date_to ) ? $date_to . ' 23:59:59' : null; 518 519 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table query with all parameters prepared. 520 $rows = $wpdb->get_results( 521 $wpdb->prepare( 522 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is escaped constant. 523 "SELECT * FROM {$table_esc} 524 WHERE ( %s IS NULL OR user_login = %s ) 525 AND ( %s IS NULL OR action = %s ) 526 AND ( %s IS NULL OR created_at >= %s ) 527 AND ( %s IS NULL OR created_at <= %s ) 528 ORDER BY id DESC 529 LIMIT %d", 530 $user_param, 531 $user_param, 532 $action_param, 533 $action_param, 534 $date_from_param, 535 $date_from_param, 536 $date_to_param, 537 $date_to_param, 538 $limit 539 ), 540 ARRAY_A 541 ); 507 // Build query using 1=1 pattern with individual prepare() calls for each filter. 508 $query = "SELECT * FROM {$table_esc} WHERE 1=1"; 509 510 if ( '' !== $user ) { 511 $query .= $wpdb->prepare( ' AND user_login = %s', $user ); 512 } 513 if ( '' !== $action_k ) { 514 $query .= $wpdb->prepare( ' AND action = %s', $action_k ); 515 } 516 if ( '' !== $date_from ) { 517 $query .= $wpdb->prepare( ' AND created_at >= %s', $date_from . ' 00:00:00' ); 518 } 519 if ( '' !== $date_to ) { 520 $query .= $wpdb->prepare( ' AND created_at <= %s', $date_to . ' 23:59:59' ); 521 } 522 523 $query .= $wpdb->prepare( ' ORDER BY id DESC LIMIT %d', $limit ); 524 525 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Query is built using $wpdb->prepare() for each parameter above. 526 $rows = $wpdb->get_results( $query, ARRAY_A ); 542 527 543 528 $export_url = wp_nonce_url( … … 546 531 ); 547 532 548 echo '<div class="wrap"><h1> 操作ログ / Activity Logs</h1>';533 echo '<div class="wrap"><h1>' . esc_html__( 'Activity Logs', 'rscsoft-activity-audit-log' ) . '</h1>'; 549 534 550 535 // Filter form. … … 555 540 echo '<table class="form-table"><tbody>'; 556 541 557 echo '<tr><th scope="row"> ユーザー / User</th><td>';558 echo '<select name="user"><option value=""> (すべて / All)</option>';542 echo '<tr><th scope="row">' . esc_html__( 'User', 'rscsoft-activity-audit-log' ) . '</th><td>'; 543 echo '<select name="user"><option value="">(' . esc_html__( 'All', 'rscsoft-activity-audit-log' ) . ')</option>'; 559 544 foreach ( $user_options as $u ) { 560 545 printf( … … 567 552 echo '</select></td></tr>'; 568 553 569 echo '<tr><th scope="row"> アクション / Action</th><td>';570 echo '<select name="action_k"><option value=""> (すべて / All)</option>';554 echo '<tr><th scope="row">' . esc_html__( 'Action', 'rscsoft-activity-audit-log' ) . '</th><td>'; 555 echo '<select name="action_k"><option value="">(' . esc_html__( 'All', 'rscsoft-activity-audit-log' ) . ')</option>'; 571 556 foreach ( $action_options as $a ) { 572 557 printf( … … 579 564 echo '</select></td></tr>'; 580 565 581 echo '<tr><th scope="row">期間 / Period</th><td>'; 582 printf( '開始 / From <input type="date" name="date_from" value="%s" /> ', esc_attr( $date_from ) ); 583 printf( '終了 / To <input type="date" name="date_to" value="%s" />', esc_attr( $date_to ) ); 566 echo '<tr><th scope="row">' . esc_html__( 'Period', 'rscsoft-activity-audit-log' ) . '</th><td>'; 567 printf( 568 '%s <input type="date" name="date_from" value="%s" /> ', 569 esc_html__( 'From', 'rscsoft-activity-audit-log' ), 570 esc_attr( $date_from ) 571 ); 572 printf( 573 '%s <input type="date" name="date_to" value="%s" />', 574 esc_html__( 'To', 'rscsoft-activity-audit-log' ), 575 esc_attr( $date_to ) 576 ); 584 577 echo '</td></tr>'; 585 578 586 579 echo '</tbody></table>'; 587 submit_button( 'フィルタを適用 / Apply Filters');580 submit_button( esc_html__( 'Apply Filters', 'rscsoft-activity-audit-log' ) ); 588 581 589 582 printf( 590 '<a class="button" style="margin-left:8px" href="%s">条件をクリア / Reset</a>', 591 esc_url( admin_url( 'admin.php?page=rscsoft-activity-audit-log' ) ) 583 '<a class="button" style="margin-left:8px" href="%s">%s</a>', 584 esc_url( admin_url( 'admin.php?page=rscsoft-activity-audit-log' ) ), 585 esc_html__( 'Reset', 'rscsoft-activity-audit-log' ) 592 586 ); 593 587 … … 596 590 // CSV export button. 597 591 printf( 598 '<p><a class="button button-primary" href="%s">CSVとしてエクスポート / Export CSV</a></p>', 599 esc_url( $export_url ) 600 ); 601 602 echo '<table class="widefat fixed striped"><thead><tr> 603 <th>日時 / Datetime</th> 604 <th>ユーザー / User</th> 605 <th>IP</th> 606 <th>アクション / Action</th> 607 <th>種別 / Type</th> 608 <th>ID</th> 609 <th>タイトル / Title</th> 610 <th>詳細 / Extra</th> 611 </tr></thead><tbody>'; 592 '<p><a class="button button-primary" href="%s">%s</a></p>', 593 esc_url( $export_url ), 594 esc_html__( 'Export CSV', 'rscsoft-activity-audit-log' ) 595 ); 596 597 echo '<table class="widefat fixed striped"><thead><tr>'; 598 echo '<th>' . esc_html__( 'Datetime', 'rscsoft-activity-audit-log' ) . '</th>'; 599 echo '<th>' . esc_html__( 'User', 'rscsoft-activity-audit-log' ) . '</th>'; 600 echo '<th>' . esc_html__( 'IP', 'rscsoft-activity-audit-log' ) . '</th>'; 601 echo '<th>' . esc_html__( 'Action', 'rscsoft-activity-audit-log' ) . '</th>'; 602 echo '<th>' . esc_html__( 'Type', 'rscsoft-activity-audit-log' ) . '</th>'; 603 echo '<th>' . esc_html__( 'ID', 'rscsoft-activity-audit-log' ) . '</th>'; 604 echo '<th>' . esc_html__( 'Title', 'rscsoft-activity-audit-log' ) . '</th>'; 605 echo '<th>' . esc_html__( 'Extra', 'rscsoft-activity-audit-log' ) . '</th>'; 606 echo '</tr></thead><tbody>'; 612 607 613 608 if ( $rows ) { … … 625 620 } 626 621 } else { 627 echo '<tr><td colspan="8"> 該当するログはありません / No logs found.</td></tr>';622 echo '<tr><td colspan="8">' . esc_html__( 'No logs found.', 'rscsoft-activity-audit-log' ) . '</td></tr>'; 628 623 } 629 624 echo '</tbody></table></div>'; … … 650 645 printf( 651 646 '<div class="updated notice"><p>%s</p></div>', 652 esc_html( sprintf( 'Settings saved. Retention: %d days.', $days_i ) ) . ' / ' . 653 esc_html( sprintf( '設定を保存しました(保持日数:%d日)。', $days_i ) ) 647 esc_html( 648 sprintf( 649 /* translators: %d: number of retention days */ 650 __( 'Settings saved. Retention: %d days.', 'rscsoft-activity-audit-log' ), 651 $days_i 652 ) 653 ) 654 654 ); 655 655 } … … 657 657 $days_i = (int) get_option( self::OPTION_RETENTION, 90 ); 658 658 659 echo '<div class="wrap"><h1> 設定 / Settings</h1>';659 echo '<div class="wrap"><h1>' . esc_html__( 'Settings', 'rscsoft-activity-audit-log' ) . '</h1>'; 660 660 echo '<form method="post">'; 661 661 wp_nonce_field( self::NONCE_SETTINGS ); 662 662 echo '<table class="form-table"><tbody>'; 663 echo '<tr><th scope="row"> ログの保持日数 / Retention (days)</th><td>';663 echo '<tr><th scope="row">' . esc_html__( 'Retention (days)', 'rscsoft-activity-audit-log' ) . '</th><td>'; 664 664 printf( 665 '<input type="number" name="retention_days" min="0" step="1" value="%s" /> 日 / days', 666 esc_attr( (string) $days_i ) 667 ); 668 echo '<p class="description">0 = 自動削除なし(無期限) / 0 = keep forever (no auto-delete)</p>'; 665 '<input type="number" name="retention_days" min="0" step="1" value="%s" /> %s', 666 esc_attr( (string) $days_i ), 667 esc_html__( 'days', 'rscsoft-activity-audit-log' ) 668 ); 669 echo '<p class="description">' . esc_html__( '0 = keep forever (no auto-delete)', 'rscsoft-activity-audit-log' ) . '</p>'; 669 670 echo '</td></tr>'; 670 671 echo '</tbody></table>'; 671 submit_button( '保存する / Save', 'primary', 'rscsoft_aal_settings_submit' );672 submit_button( esc_html__( 'Save', 'rscsoft-activity-audit-log' ), 'primary', 'rscsoft_aal_settings_submit' ); 672 673 echo '</form></div>'; 673 674 } … … 773 774 endif; 774 775 776 // Register activation/deactivation hooks. 777 register_activation_hook( __FILE__, array( 'RSCSoft_Activity_Audit_Log', 'activate' ) ); 778 register_deactivation_hook( __FILE__, array( 'RSCSoft_Activity_Audit_Log', 'deactivate' ) ); 779 780 // Load bundled translations if not available from WordPress.org. 781 $rscsoft_aal_locale = determine_locale(); 782 $rscsoft_aal_mofile = __DIR__ . '/languages/rscsoft-activity-audit-log-' . $rscsoft_aal_locale . '.mo'; 783 if ( file_exists( $rscsoft_aal_mofile ) ) { 784 load_textdomain( 'rscsoft-activity-audit-log', $rscsoft_aal_mofile ); 785 } 786 unset( $rscsoft_aal_locale, $rscsoft_aal_mofile ); 787 788 // Initialize plugin immediately to catch all hooks including wp_login. 775 789 new RSCSoft_Activity_Audit_Log();
Note: See TracChangeset
for help on using the changeset viewer.