Plugin Directory

Changeset 3416922


Ignore:
Timestamp:
12/11/2025 03:22:29 AM (2 months ago)
Author:
rscsoft
Message:

20251211 Version 1.2.1: Fix log display bug and add Japanese translation

  • Fixed: Logs were not displayed on the admin screen due to query issue
  • Added: Japanese (ja) translation support with bundled .mo file
Location:
rscsoft-activity-audit-log/trunk
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • rscsoft-activity-audit-log/trunk/readme.txt

    r3414225 r3416922  
    55Requires at least: 6.0
    66Tested up to: 6.9
    7 Stable tag: 1.2.0
     7Stable tag: 1.2.1
    88Requires PHP: 7.4
    99License: GPLv2 or later
     
    7171== Changelog ==
    7272
     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
    7379= 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.
    7581  初回公開バージョン:操作ログ記録、CSVエクスポート、保持日数設定、自動削除を実装。
    7682
    7783== Upgrade Notice ==
    78 1.2.0 – First public release. 
    79 1.2.0 – 初回公開バージョン。
     84
     85= 1.2.1 =
     86Bug fix for log display and Japanese translation support.
     87ログ表示のバグ修正と日本語翻訳対応。
     88
     89= 1.2.0 =
     90First public release.
     91初回公開バージョン。
  • rscsoft-activity-audit-log/trunk/rscsoft-activity-audit-log.php

    r3414225 r3416922  
    33 * Plugin Name: RSCSoft Activity Audit Log
    44 * 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.0
     5 * Version: 1.2.1
    66 * Author: Masahiro Sakamoto
    77 * Author URI: https://profiles.wordpress.org/rscsoft/
     
    3838
    3939        /**
    40          * Constructor. Registers hooks for activation, admin menu, and event logging.
     40         * Constructor. Registers hooks for admin menu and event logging.
    4141         */
    4242        public function __construct() {
    43             register_activation_hook( __FILE__, array( $this, 'activate' ) );
    44             register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
    45 
    4643            add_action( 'admin_menu', array( $this, 'admin_menu' ) );
    4744            add_action( 'admin_post_rscsoft_aal_export_csv', array( $this, 'export_csv' ) );
     
    124121         * 有効化時:テーブル作成 + デフォルト保持日数 + Cron登録.
    125122         */
    126         public function activate() {
     123        public static function activate() {
    127124            global $wpdb;
    128125
     
    132129            }
    133130
    134             $table   = $this->table_name();
     131            $table   = $wpdb->prefix . 'rscsoft_aal_log';
    135132            $charset = $wpdb->get_charset_collate();
    136133
     
    175172         * Plugin deactivation handler. Unschedules the cleanup cron event.
    176173         */
    177         public function deactivate() {
     174        public static function deactivate() {
    178175            $timestamp = wp_next_scheduled( self::CRON_HOOK );
    179176            if ( $timestamp ) {
     
    452449        public function admin_menu() {
    453450            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' ),
    456453                'manage_options',
    457454                'rscsoft-activity-audit-log',
     
    462459            add_submenu_page(
    463460                'rscsoft-activity-audit-log',
    464                 'Settings',
    465                 'Settings',
     461                esc_html__( 'Settings', 'rscsoft-activity-audit-log' ),
     462                esc_html__( 'Settings', 'rscsoft-activity-audit-log' ),
    466463                'manage_options',
    467464                'rscsoft-activity-audit-log-settings',
     
    508505            $action_options = $wpdb->get_col( "SELECT DISTINCT action FROM {$table_esc} ORDER BY action ASC" );
    509506
    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 );
    542527
    543528            $export_url = wp_nonce_url(
     
    546531            );
    547532
    548             echo '<div class="wrap"><h1>操作ログ / Activity Logs</h1>';
     533            echo '<div class="wrap"><h1>' . esc_html__( 'Activity Logs', 'rscsoft-activity-audit-log' ) . '</h1>';
    549534
    550535            // Filter form.
     
    555540            echo '<table class="form-table"><tbody>';
    556541
    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>';
    559544            foreach ( $user_options as $u ) {
    560545                printf(
     
    567552            echo '</select></td></tr>';
    568553
    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>';
    571556            foreach ( $action_options as $a ) {
    572557                printf(
     
    579564            echo '</select></td></tr>';
    580565
    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            );
    584577            echo '</td></tr>';
    585578
    586579            echo '</tbody></table>';
    587             submit_button( 'フィルタを適用 / Apply Filters' );
     580            submit_button( esc_html__( 'Apply Filters', 'rscsoft-activity-audit-log' ) );
    588581
    589582            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' )
    592586            );
    593587
     
    596590            // CSV export button.
    597591            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>';
    612607
    613608            if ( $rows ) {
     
    625620                }
    626621            } 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>';
    628623            }
    629624            echo '</tbody></table></div>';
     
    650645                printf(
    651646                    '<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                    )
    654654                );
    655655            }
     
    657657            $days_i = (int) get_option( self::OPTION_RETENTION, 90 );
    658658
    659             echo '<div class="wrap"><h1>設定 / Settings</h1>';
     659            echo '<div class="wrap"><h1>' . esc_html__( 'Settings', 'rscsoft-activity-audit-log' ) . '</h1>';
    660660            echo '<form method="post">';
    661661            wp_nonce_field( self::NONCE_SETTINGS );
    662662            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>';
    664664            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>';
    669670            echo '</td></tr>';
    670671            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' );
    672673            echo '</form></div>';
    673674        }
     
    773774endif;
    774775
     776// Register activation/deactivation hooks.
     777register_activation_hook( __FILE__, array( 'RSCSoft_Activity_Audit_Log', 'activate' ) );
     778register_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';
     783if ( file_exists( $rscsoft_aal_mofile ) ) {
     784    load_textdomain( 'rscsoft-activity-audit-log', $rscsoft_aal_mofile );
     785}
     786unset( $rscsoft_aal_locale, $rscsoft_aal_mofile );
     787
     788// Initialize plugin immediately to catch all hooks including wp_login.
    775789new RSCSoft_Activity_Audit_Log();
Note: See TracChangeset for help on using the changeset viewer.