Plugin Directory

Changeset 3692532


Ignore:
Timestamp:
09/12/2026 09:48:09 AM (6 weeks ago)
Author:
nersesgh
Message:

version 1.1.0

Location:
feed-health-monitor-for-woocommerce/trunk
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • feed-health-monitor-for-woocommerce/trunk/admin/class-admin.php

    r3678464 r3692532  
    4141                        array( $this, 'render_settings' )
    4242                );
     43
     44                add_submenu_page(
     45                        'woocommerce',
     46                        __( 'Scan History', 'feed-health-monitor-for-woocommerce' ),
     47                        __( 'Scan History', 'feed-health-monitor-for-woocommerce' ),
     48                        'manage_woocommerce',
     49                        'wcfhm-history',
     50                        array( $this, 'render_history' )
     51                );
    4352        }
    4453
    … …  
    6372                register_setting( 'wcfhm_settings', 'wcfhm_mpn_meta_key', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) );
    6473                register_setting( 'wcfhm_settings', 'wcfhm_enable_mpn_validation', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) );
     74
     75                register_setting( 'wcfhm_settings', 'wcfhm_enable_monitoring', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) );
     76                register_setting( 'wcfhm_settings', 'wcfhm_scan_frequency', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) );
     77                register_setting( 'wcfhm_settings', 'wcfhm_email_notifications', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) );
     78                register_setting( 'wcfhm_settings', 'wcfhm_notification_email', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_email' ) );
     79                register_setting( 'wcfhm_settings', 'wcfhm_score_threshold', array( 'type' => 'integer', 'sanitize_callback' => 'absint' ) );
     80                register_setting( 'wcfhm_settings', 'wcfhm_notify_critical', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) );
     81                register_setting( 'wcfhm_settings', 'wcfhm_notify_warnings', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ) );
     82                register_setting( 'wcfhm_settings', 'wcfhm_retention_days', array( 'type' => 'integer', 'sanitize_callback' => 'absint' ) );
    6583        }
    6684
    … …  
    122140                include WCFHM_PLUGIN_DIR . 'admin/views/settings.php';
    123141        }
     142
     143        public function render_history() {
     144                include WCFHM_PLUGIN_DIR . 'admin/views/history.php';
     145        }
    124146}
  • feed-health-monitor-for-woocommerce/trunk/admin/views/dashboard.php

    r3678464 r3692532  
    55
    66$wcfhm_latest_scan = WCFHM_Repository::get_latest_scan();
     7$wcfhm_is_monitoring = get_option( 'wcfhm_enable_monitoring', 'no' ) === 'yes';
     8$wcfhm_next_scan = wp_next_scheduled( 'wcfhm_scheduled_scan' );
    79?>
    810<div class="wrap wcfhm-wrap">
    … …  
    1214                <a href="?page=wcfhm-dashboard" class="nav-tab nav-tab-active"><?php esc_html_e( 'Dashboard', 'feed-health-monitor-for-woocommerce' ); ?></a>
    1315                <a href="?page=wcfhm-issues" class="nav-tab"><?php esc_html_e( 'Issues', 'feed-health-monitor-for-woocommerce' ); ?></a>
     16                <a href="?page=wcfhm-history" class="nav-tab"><?php esc_html_e( 'Scan History', 'feed-health-monitor-for-woocommerce' ); ?></a>
    1417                <a href="?page=wcfhm-settings" class="nav-tab"><?php esc_html_e( 'Settings', 'feed-health-monitor-for-woocommerce' ); ?></a>
    1518        </h2>
    … …  
    2124                        <p class="wcfhm-progress-text"><?php esc_html_e( 'Scanning products...', 'feed-health-monitor-for-woocommerce' ); ?> <span id="wcfhm-scan-count">0 / 0</span></p>
    2225                </div>
     26        </div>
     27
     28        <div class="wcfhm-dashboard-widgets" style="margin-bottom: 20px;">
     29                <div class="wcfhm-widget">
     30                        <h3><?php esc_html_e( 'Monitoring', 'feed-health-monitor-for-woocommerce' ); ?></h3>
     31                        <table class="wcfhm-summary-table">
     32                                <tr>
     33                                        <td><?php esc_html_e( 'Status', 'feed-health-monitor-for-woocommerce' ); ?></td>
     34                                        <td><strong><?php echo $wcfhm_is_monitoring ? '<span style="color: green;">● Active</span>' : '<span style="color: #d63638;">● Disabled</span>'; ?></strong></td>
     35                                </tr>
     36                                <?php if ( $wcfhm_is_monitoring ) : ?>
     37                                        <tr>
     38                                                <td><?php esc_html_e( 'Frequency', 'feed-health-monitor-for-woocommerce' ); ?></td>
     39                                                <td><strong><?php echo esc_html( ucfirst( str_replace( 'wcfhm_', '', get_option( 'wcfhm_scan_frequency', 'weekly' ) ) ) ); ?></strong></td>
     40                                        </tr>
     41                                        <tr>
     42                                                <td><?php esc_html_e( 'Next Scan', 'feed-health-monitor-for-woocommerce' ); ?></td>
     43                                                <td><strong><?php echo $wcfhm_next_scan ? esc_html( wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $wcfhm_next_scan ) ) : esc_html__( 'Not scheduled', 'feed-health-monitor-for-woocommerce' ); ?></strong></td>
     44                                        </tr>
     45                                <?php endif; ?>
     46                        </table>
     47                        <p style="margin-top: 15px;"><a href="?page=wcfhm-settings" class="button button-secondary"><?php esc_html_e( 'Configure Monitoring', 'feed-health-monitor-for-woocommerce' ); ?></a></p>
     48                </div>
     49
     50                <?php if ( $wcfhm_latest_scan ) : ?>
     51                        <?php
     52                                $wcfhm_previous_scan = WCFHM_Repository::get_previous_scan( $wcfhm_latest_scan->id );
     53                                $wcfhm_score_diff = 0;
     54                                if ( $wcfhm_previous_scan ) {
     55                                        $wcfhm_score_diff = (int) $wcfhm_latest_scan->health_score - (int) $wcfhm_previous_scan->health_score;
     56                                }
     57                        ?>
     58                        <div class="wcfhm-widget">
     59                                <h3><?php esc_html_e( 'Latest Changes', 'feed-health-monitor-for-woocommerce' ); ?></h3>
     60                                <table class="wcfhm-summary-table">
     61                                        <tr>
     62                                                <td><?php esc_html_e( 'New Issues', 'feed-health-monitor-for-woocommerce' ); ?></td>
     63                                                <td><strong><?php echo esc_html( (string) $wcfhm_latest_scan->new_issues ); ?></strong></td>
     64                                        </tr>
     65                                        <tr>
     66                                                <td><?php esc_html_e( 'Fixed Issues', 'feed-health-monitor-for-woocommerce' ); ?></td>
     67                                                <td><strong><?php echo esc_html( (string) $wcfhm_latest_scan->fixed_issues ); ?></strong></td>
     68                                        </tr>
     69                                        <tr>
     70                                                <td><?php esc_html_e( 'Score Change', 'feed-health-monitor-for-woocommerce' ); ?></td>
     71                                                <td>
     72                                                        <strong>
     73                                                                <?php if ( $wcfhm_score_diff > 0 ) : ?>
     74                                                                        <span style="color: green;">↑ <?php echo esc_html( (string) $wcfhm_score_diff ); ?> points</span>
     75                                                                <?php elseif ( $wcfhm_score_diff < 0 ) : ?>
     76                                                                        <span style="color: #d63638;">↓ <?php echo esc_html( (string) abs( $wcfhm_score_diff ) ); ?> points</span>
     77                                                                <?php else : ?>
     78                                                                        <span style="color: #666;">No change</span>
     79                                                                <?php endif; ?>
     80                                                        </strong>
     81                                                </td>
     82                                        </tr>
     83                                </table>
     84                                <p style="margin-top: 15px;"><a href="?page=wcfhm-history" class="button button-secondary"><?php esc_html_e( 'View History', 'feed-health-monitor-for-woocommerce' ); ?></a></p>
     85                        </div>
     86                <?php endif; ?>
    2387        </div>
    2488
  • feed-health-monitor-for-woocommerce/trunk/admin/views/issues.php

    r3678464 r3692532  
    5757                <a href="?page=wcfhm-dashboard" class="nav-tab"><?php esc_html_e( 'Dashboard', 'feed-health-monitor-for-woocommerce' ); ?></a>
    5858                <a href="?page=wcfhm-issues" class="nav-tab nav-tab-active"><?php esc_html_e( 'Issues', 'feed-health-monitor-for-woocommerce' ); ?></a>
     59                <a href="?page=wcfhm-history" class="nav-tab"><?php esc_html_e( 'Scan History', 'feed-health-monitor-for-woocommerce' ); ?></a>
    5960                <a href="?page=wcfhm-settings" class="nav-tab"><?php esc_html_e( 'Settings', 'feed-health-monitor-for-woocommerce' ); ?></a>
    6061        </h2>
  • feed-health-monitor-for-woocommerce/trunk/admin/views/settings.php

    r3678464 r3692532  
    1010                <a href="?page=wcfhm-dashboard" class="nav-tab"><?php esc_html_e( 'Dashboard', 'feed-health-monitor-for-woocommerce' ); ?></a>
    1111                <a href="?page=wcfhm-issues" class="nav-tab"><?php esc_html_e( 'Issues', 'feed-health-monitor-for-woocommerce' ); ?></a>
     12                <a href="?page=wcfhm-history" class="nav-tab"><?php esc_html_e( 'Scan History', 'feed-health-monitor-for-woocommerce' ); ?></a>
    1213                <a href="?page=wcfhm-settings" class="nav-tab nav-tab-active"><?php esc_html_e( 'Settings', 'feed-health-monitor-for-woocommerce' ); ?></a>
    1314        </h2>
    … …  
    1718                <?php do_settings_sections( 'wcfhm_settings' ); ?>
    1819               
     20                <h2><?php esc_html_e( 'General Settings', 'feed-health-monitor-for-woocommerce' ); ?></h2>
    1921                <table class="form-table">
    2022                        <tr valign="top">
    … …  
    5658                        </tr>
    5759                </table>
     60
     61                <hr>
     62
     63                <h2><?php esc_html_e( 'Monitoring & Notifications', 'feed-health-monitor-for-woocommerce' ); ?></h2>
     64                <table class="form-table">
     65                        <tr valign="top">
     66                                <th scope="row"><?php esc_html_e( 'Enable monitoring', 'feed-health-monitor-for-woocommerce' ); ?></th>
     67                                <td>
     68                                        <label>
     69                                                <input type="checkbox" name="wcfhm_enable_monitoring" value="yes" <?php checked( get_option( 'wcfhm_enable_monitoring', 'no' ), 'yes' ); ?> />
     70                                                <?php esc_html_e( 'Automatically run catalog scans in the background.', 'feed-health-monitor-for-woocommerce' ); ?>
     71                                        </label>
     72                                </td>
     73                        </tr>
     74                        <tr valign="top">
     75                                <th scope="row"><?php esc_html_e( 'Scan frequency', 'feed-health-monitor-for-woocommerce' ); ?></th>
     76                                <td>
     77                                        <select name="wcfhm_scan_frequency">
     78                                                <option value="daily" <?php selected( get_option( 'wcfhm_scan_frequency', 'wcfhm_weekly' ), 'daily' ); ?>><?php esc_html_e( 'Daily', 'feed-health-monitor-for-woocommerce' ); ?></option>
     79                                                <option value="wcfhm_weekly" <?php selected( get_option( 'wcfhm_scan_frequency', 'wcfhm_weekly' ), 'wcfhm_weekly' ); ?>><?php esc_html_e( 'Weekly', 'feed-health-monitor-for-woocommerce' ); ?></option>
     80                                        </select>
     81                                </td>
     82                        </tr>
     83                        <tr valign="top">
     84                                <th scope="row"><?php esc_html_e( 'Email notifications', 'feed-health-monitor-for-woocommerce' ); ?></th>
     85                                <td>
     86                                        <label>
     87                                                <input type="checkbox" name="wcfhm_email_notifications" value="yes" <?php checked( get_option( 'wcfhm_email_notifications', 'no' ), 'yes' ); ?> />
     88                                                <?php esc_html_e( 'Send email alerts after a scheduled scan.', 'feed-health-monitor-for-woocommerce' ); ?>
     89                                        </label>
     90                                </td>
     91                        </tr>
     92                        <tr valign="top">
     93                                <th scope="row"><?php esc_html_e( 'Notification email', 'feed-health-monitor-for-woocommerce' ); ?></th>
     94                                <td>
     95                                        <input type="email" name="wcfhm_notification_email" value="<?php echo esc_attr( get_option( 'wcfhm_notification_email', get_option( 'admin_email' ) ) ); ?>" class="regular-text" />
     96                                </td>
     97                        </tr>
     98                        <tr valign="top">
     99                                <th scope="row"><?php esc_html_e( 'Notify for new critical issues', 'feed-health-monitor-for-woocommerce' ); ?></th>
     100                                <td>
     101                                        <label>
     102                                                <input type="checkbox" name="wcfhm_notify_critical" value="yes" <?php checked( get_option( 'wcfhm_notify_critical', 'no' ), 'yes' ); ?> />
     103                                        </label>
     104                                </td>
     105                        </tr>
     106                        <tr valign="top">
     107                                <th scope="row"><?php esc_html_e( 'Notify for new warnings', 'feed-health-monitor-for-woocommerce' ); ?></th>
     108                                <td>
     109                                        <label>
     110                                                <input type="checkbox" name="wcfhm_notify_warnings" value="yes" <?php checked( get_option( 'wcfhm_notify_warnings', 'no' ), 'yes' ); ?> />
     111                                        </label>
     112                                </td>
     113                        </tr>
     114                        <tr valign="top">
     115                                <th scope="row"><?php esc_html_e( 'Health score decrease threshold', 'feed-health-monitor-for-woocommerce' ); ?></th>
     116                                <td>
     117                                        <input type="number" name="wcfhm_score_threshold" value="<?php echo esc_attr( get_option( 'wcfhm_score_threshold', 10 ) ); ?>" min="1" step="1" />
     118                                        <p class="description"><?php esc_html_e( 'Send an alert if the health score decreases by this many points or more compared to the previous scan.', 'feed-health-monitor-for-woocommerce' ); ?></p>
     119                                </td>
     120                        </tr>
     121                        <tr valign="top">
     122                                <th scope="row"><?php esc_html_e( 'Keep scan history for', 'feed-health-monitor-for-woocommerce' ); ?></th>
     123                                <td>
     124                                        <select name="wcfhm_retention_days">
     125                                                <option value="7" <?php selected( get_option( 'wcfhm_retention_days', 30 ), 7 ); ?>><?php esc_html_e( '7 days', 'feed-health-monitor-for-woocommerce' ); ?></option>
     126                                                <option value="30" <?php selected( get_option( 'wcfhm_retention_days', 30 ), 30 ); ?>><?php esc_html_e( '30 days', 'feed-health-monitor-for-woocommerce' ); ?></option>
     127                                                <option value="90" <?php selected( get_option( 'wcfhm_retention_days', 30 ), 90 ); ?>><?php esc_html_e( '90 days', 'feed-health-monitor-for-woocommerce' ); ?></option>
     128                                        </select>
     129                                </td>
     130                        </tr>
     131                </table>
    58132               
    59133                <?php submit_button(); ?>
  • feed-health-monitor-for-woocommerce/trunk/feed-health-monitor.php

    r3687628 r3692532  
    33 * Plugin Name: Feed Health Monitor for WooCommerce
    44 * Description: Scan your WooCommerce catalog for product data issues that may affect Google Shopping and product feeds.
    5  * Version: 1.0.1
     5 * Version: 1.1.0
    66 * Requires at least: 6.5
    77 * Requires PHP: 7.4
    … …  
    1818}
    1919
    20 define( 'WCFHM_VERSION', '1.0.0' );
     20define( 'WCFHM_VERSION', '1.1.0' );
    2121define( 'WCFHM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    2222define( 'WCFHM_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
    … …  
    3636        require_once WCFHM_PLUGIN_DIR . 'includes/class-csv-exporter.php';
    3737        require_once WCFHM_PLUGIN_DIR . 'admin/class-admin.php';
     38        require_once WCFHM_PLUGIN_DIR . 'includes/class-monitor.php';
    3839        require_once WCFHM_PLUGIN_DIR . 'includes/class-plugin.php';
    3940
    … …  
    5455        require_once WCFHM_PLUGIN_DIR . 'includes/class-repository.php';
    5556        WCFHM_Repository::create_tables();
     57
     58        if ( ! wp_next_scheduled( 'wcfhm_retention_cleanup' ) ) {
     59                wp_schedule_event( time(), 'daily', 'wcfhm_retention_cleanup' );
     60        }
    5661}
     62
     63add_filter( 'cron_schedules', 'wcfhm_add_cron_schedules' );
     64function wcfhm_add_cron_schedules( $schedules ) {
     65        $schedules['wcfhm_weekly'] = array(
     66                'interval' => 7 * DAY_IN_SECONDS,
     67                'display'  => __( 'Once Weekly', 'feed-health-monitor-for-woocommerce' ),
     68        );
     69        return $schedules;
     70}
  • feed-health-monitor-for-woocommerce/trunk/includes/class-plugin.php

    r3678464 r3692532  
    1111                $scanner = new WCFHM_Scanner();
    1212                $scanner->init();
     13
     14                $monitor = new WCFHM_Monitor();
     15                $monitor->init();
    1316        }
    1417}
  • feed-health-monitor-for-woocommerce/trunk/includes/class-repository.php

    r3678464 r3692532  
    2424                        info_count int(11) DEFAULT 0 NOT NULL,
    2525                        health_score int(11) DEFAULT 0 NOT NULL,
     26                        scan_type varchar(20) DEFAULT 'manual' NOT NULL,
     27                        new_issues int(11) DEFAULT 0 NOT NULL,
     28                        fixed_issues int(11) DEFAULT 0 NOT NULL,
    2629                        PRIMARY KEY  (id)
    2730                ) $charset_collate;
    … …  
    4447        }
    4548
    46         public static function create_scan() {
     49        public static function create_scan( $type = 'manual' ) {
    4750                global $wpdb;
    4851                $table_scans = $wpdb->prefix . 'feed_health_scans';
    … …  
    5255                        array(
    5356                                'started_at' => current_time( 'mysql' ),
     57                                'scan_type'  => $type,
    5458                        )
    5559                );
    … …  
    140144                return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}feed_health_issues WHERE scan_id = %d AND product_id = %d", $scan_id, $product_id ) );
    141145        }
     146
     147        public static function get_scan( $scan_id ) {
     148                global $wpdb;
     149                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
     150                return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}feed_health_scans WHERE id = %d", $scan_id ) );
     151        }
     152
     153        public static function get_previous_scan( $scan_id ) {
     154                global $wpdb;
     155                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
     156                return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}feed_health_scans WHERE id < %d AND completed_at != '0000-00-00 00:00:00' ORDER BY id DESC LIMIT 1", $scan_id ) );
     157        }
     158
     159        public static function get_new_issues_count( $current_scan_id, $previous_scan_id, $severity = null ) {
     160                global $wpdb;
     161                $query = "SELECT COUNT(*) FROM {$wpdb->prefix}feed_health_issues cur
     162                        LEFT JOIN {$wpdb->prefix}feed_health_issues prev
     163                        ON cur.product_id = prev.product_id AND cur.issue_code = prev.issue_code AND prev.scan_id = %d
     164                        WHERE cur.scan_id = %d AND prev.id IS NULL";
     165               
     166                $values = array( $previous_scan_id, $current_scan_id );
     167
     168                if ( $severity ) {
     169                        $query .= " AND cur.severity = %s";
     170                        $values[] = $severity;
     171                }
     172
     173                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
     174                return (int) $wpdb->get_var( $wpdb->prepare( $query, $values ) );
     175        }
     176
     177        public static function get_fixed_issues_count( $current_scan_id, $previous_scan_id ) {
     178                global $wpdb;
     179                $query = "SELECT COUNT(*) FROM {$wpdb->prefix}feed_health_issues prev
     180                        LEFT JOIN {$wpdb->prefix}feed_health_issues cur
     181                        ON prev.product_id = cur.product_id AND prev.issue_code = cur.issue_code AND cur.scan_id = %d
     182                        WHERE prev.scan_id = %d AND cur.id IS NULL";
     183               
     184                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
     185                return (int) $wpdb->get_var( $wpdb->prepare( $query, $current_scan_id, $previous_scan_id ) );
     186        }
     187
     188        public static function get_scan_history( $limit = 20, $offset = 0 ) {
     189                global $wpdb;
     190                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
     191                return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}feed_health_scans WHERE completed_at != '0000-00-00 00:00:00' ORDER BY id DESC LIMIT %d OFFSET %d", $limit, $offset ) );
     192        }
     193
     194        public static function count_scan_history() {
     195                global $wpdb;
     196                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
     197                return $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}feed_health_scans WHERE completed_at != '0000-00-00 00:00:00'" );
     198        }
     199
     200        public static function delete_old_scans( $days ) {
     201                global $wpdb;
     202                $date = date( 'Y-m-d H:i:s', strtotime( "-$days days" ) );
     203
     204                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
     205                $old_scans = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}feed_health_scans WHERE started_at < %s", $date ) );
     206
     207                if ( ! empty( $old_scans ) ) {
     208                        $ids = implode( ',', array_map( 'intval', $old_scans ) );
     209                        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
     210                        $wpdb->query( "DELETE FROM {$wpdb->prefix}feed_health_issues WHERE scan_id IN ($ids)" );
     211                        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
     212                        $wpdb->query( "DELETE FROM {$wpdb->prefix}feed_health_scans WHERE id IN ($ids)" );
     213                }
     214        }
    142215}
  • feed-health-monitor-for-woocommerce/trunk/includes/class-scanner.php

    r3678464 r3692532  
    1717                }
    1818
     19                $result = $this->start_scan( 'manual' );
     20               
     21                if ( is_wp_error( $result ) ) {
     22                        wp_send_json_error( $result->get_error_message() );
     23                }
     24
     25                wp_send_json_success( $result );
     26        }
     27
     28        public function start_scan( $type = 'manual' ) {
    1929                if ( get_transient( 'wcfhm_scan_lock' ) ) {
    20                         wp_send_json_error( 'A scan is already in progress.' );
     30                        return new WP_Error( 'locked', 'A scan is already in progress.' );
    2131                }
    2232
    2333                set_transient( 'wcfhm_scan_lock', true, 60 * 60 );
    2434
    25                 $scan_id = WCFHM_Repository::create_scan();
     35                $scan_id = WCFHM_Repository::create_scan( $type );
    2636
    2737                $total_products = wp_count_posts( 'product' );
    2838                $total = (int) $total_products->publish + (int) $total_products->draft + (int) $total_products->pending + (int) $total_products->private;
    2939
    30                 wp_send_json_success( array(
     40                return array(
    3141                        'scan_id' => $scan_id,
    3242                        'total'   => $total,
    3343                        'page'    => 1,
    34                 ) );
     44                );
    3545        }
    3646
    … …  
    4858                }
    4959
     60                $result = $this->process_batch( $scan_id, $page );
     61               
     62                if ( is_wp_error( $result ) ) {
     63                        wp_send_json_error( $result->get_error_message() );
     64                }
     65
     66                wp_send_json_success( $result );
     67        }
     68
     69        public function process_batch( $scan_id, $page ) {
    5070                $batch_size = (int) get_option( 'wcfhm_batch_size', 50 );
    5171                if ( $batch_size < 1 ) {
    … …  
    6686                if ( empty( $product_ids ) ) {
    6787                        $this->complete_scan( $scan_id );
    68                         delete_transient( 'wcfhm_scan_lock' );
    69                         wp_send_json_success( array( 'completed' => true ) );
     88                        return array( 'completed' => true );
    7089                }
    7190
    … …  
    83102                WCFHM_Repository::insert_issues( $all_issues );
    84103
    85                 wp_send_json_success( array(
     104                return array(
    86105                        'processed' => count( $product_ids ),
    87106                        'next_page' => $page + 1,
    88107                        'completed' => false,
    89                 ) );
     108                );
    90109        }
    91110
    92         private function complete_scan( $scan_id ) {
     111        public function complete_scan( $scan_id ) {
    93112                $total_products = wp_count_posts( 'product' );
    94113                $total = (int) $total_products->publish + (int) $total_products->draft + (int) $total_products->pending + (int) $total_products->private;
    … …  
    118137                        'health_score'     => $score,
    119138                ) );
     139
     140                delete_transient( 'wcfhm_scan_lock' );
     141                do_action( 'wcfhm_scan_completed', $scan_id );
    120142        }
    121143}
  • feed-health-monitor-for-woocommerce/trunk/readme.txt

    r3687628 r3692532  
    44Requires at least: 6.5
    55Tested up to: 7.1
    6 Stable tag: 1.0.1
     6Stable tag: 1.1.0
    77Requires PHP: 7.4
    88License: GPLv2 or later
    … …  
    6666* Developers maintaining product catalogs
    6767
     68### Continuous Monitoring & Alerts
     69
     70With version 1.1.0, Feed Health Monitor now acts as an active watchdog:
     71* Schedule automated background scans (Daily or Weekly).
     72* Compare current catalog health against historical scan data.
     73* View scan history with new vs. fixed issues metrics.
     74* Get email notifications when critical issues appear or the health score drops.
     75
    6876### Free and Lightweight
    6977
    … …  
    8694== Changelog ==
    8795
     96= 1.1.0 =
     97* New: Background scheduled scans via WP Cron (Daily/Weekly).
     98* New: Scan history view to compare historical trends.
     99* New: Detect newly introduced issues and recently fixed issues.
     100* New: Optional email alerts for critical issues and health score drops.
     101* Tweak: Added data retention cleanup tasks.
     102
    88103= 1.0.0 =
    89104* Initial release
  • feed-health-monitor-for-woocommerce/trunk/uninstall.php

    r3678464 r3692532  
    66global $wpdb;
    77
     8wp_clear_scheduled_hook( 'wcfhm_scheduled_scan' );
     9wp_clear_scheduled_hook( 'wcfhm_retention_cleanup' );
     10// Note: single events like 'wcfhm_scheduled_scan_batch' may be running or scheduled, unschedule all of them:
     11wp_unschedule_hook( 'wcfhm_scheduled_scan_batch' );
     12
    813// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared
    914$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}feed_health_issues" );
Note: See TracChangeset for help on using the changeset viewer.