/**
 * One-shot Giovision FPM/AS recovery (13 Aug 2026).
 * Cancels stuck gammetec_worker_tick in-progress, pauses Gammatec workers,
 * prunes old Action Scheduler complete rows. Self-disables after one run.
 */
if (!defined('ABSPATH')) {
  exit;
}

add_action('plugins_loaded', static function (): void {
  if (get_option('oncreate_giovision_as_recover_20260813_done')) {
    return;
  }
  if (!function_exists('as_get_scheduled_actions') && !class_exists('ActionScheduler_Store')) {
    return;
  }

  $report = [
    'cancelled_in_progress' => 0,
    'failed_in_progress' => 0,
    'unsched_pending' => 0,
    'pruned_complete' => 0,
    'gammetec_paused' => 0,
    'errors' => [],
  ];

  try {
    if (function_exists('as_unschedule_all_actions')) {
      as_unschedule_all_actions('gammetec_worker_tick', [], 'gammetec-sync');
      $report['unsched_pending'] = 1;
    }

    if (class_exists('ActionScheduler') && method_exists('ActionScheduler', 'store')) {
      $store = ActionScheduler::store();
      $ids = $store->query_actions([
        'hook' => 'gammetec_worker_tick',
        'status' => ActionScheduler_Store::STATUS_RUNNING,
        'per_page' => 50,
        'orderby' => 'none',
      ]);
      foreach ((array) $ids as $action_id) {
        $action_id = (int) $action_id;
        if ($action_id <= 0) {
          continue;
        }
        try {
          if (method_exists($store, 'cancel_action')) {
            $store->cancel_action($action_id);
            $report['cancelled_in_progress']++;
          } elseif (method_exists($store, 'mark_failure')) {
            $store->mark_failure($action_id);
            $report['failed_in_progress']++;
          }
        } catch (Throwable $e) {
          $report['errors'][] = 'cancel#' . $action_id . ':' . $e->getMessage();
        }
      }
    }

    // Pause Gammatec background workers (operator can Resume later).
    if (defined('GAMMETEC_WORKERS_PAUSED_OPTION')) {
      update_option(GAMMETEC_WORKERS_PAUSED_OPTION, 1, false);
      $report['gammetec_paused'] = 1;
    } else {
      update_option('gammetec_workers_paused', 1, false);
      $report['gammetec_paused'] = 1;
    }
    // Same for NONAPI if present.
    update_option('nonapi_workers_paused', 1, false);

    // Prune Complete AS history older than 7 days (cap batches to avoid long FPM hold).
    global $wpdb;
    if (isset($wpdb) && is_object($wpdb)) {
      $table = $wpdb->prefix . 'actionscheduler_actions';
      $exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table));
      if ($exists === $table) {
        $cutoff = gmdate('Y-m-d H:i:s', time() - (7 * DAY_IN_SECONDS));
        for ($i = 0; $i < 20; $i++) {
          // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
          $deleted = $wpdb->query(
            $wpdb->prepare(
              "DELETE FROM {$table} WHERE status = %s AND scheduled_date_gmt < %s LIMIT 5000",
              'complete',
              $cutoff
            )
          );
          if (!is_numeric($deleted) || (int) $deleted <= 0) {
            break;
          }
          $report['pruned_complete'] += (int) $deleted;
          if ((int) $deleted < 5000) {
            break;
          }
        }
      }
    }
  } catch (Throwable $e) {
    $report['errors'][] = $e->getMessage();
  }

  update_option('oncreate_giovision_as_recover_20260813_done', [
    'at' => gmdate('c'),
    'report' => $report,
  ], false);
}, 5);


add_action('wp_ajax_oncreate_giovision_as_recover_status', static function (): void {
  if (!current_user_can('manage_woocommerce') && !current_user_can('manage_options')) {
    wp_send_json_error(['message' => 'Forbidden'], 403);
  }
  wp_send_json_success(get_option('oncreate_giovision_as_recover_20260813_done', null));
});
<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet type='text/xml' href='//giovision.co.za/?wds_sitemap_styling=1&#038;template=sitemapIndexBody'?><!-- SMARTCRAWL SITEMAP -->
<sitemapindex
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd"
	xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
			<sitemap><loc>https://giovision.co.za/page-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/elementor_library-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/product-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/product-sitemap2.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/product-sitemap3.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/product-sitemap4.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/ts_footer_block-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/br_product_filter-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/product_brand-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/product_cat-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/product_tag-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/ts_product_brand-sitemap1.xml</loc></sitemap>			<sitemap><loc>https://giovision.co.za/extras-sitemap1.xml</loc></sitemap>	</sitemapindex>