HEX
Server: nginx/1.29.3
System: Linux 11979.bigscoots-wpo.com 6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025 x86_64
User: nginx (1068)
PHP: 7.4.33
Disabled: exec,system,passthru,shell_exec,proc_open,proc_close,popen,show_source,cmd# Do not modify this line # 1684243876
Upload Files
File: //bigscoots/wpo/extras/shop-monitor.sh
#!/bin/bash
# Bootstrap installer: sets up a per-domain Woo "shop page monitor" and a systemd unit.
# Usage:
#    bash /home/nginx/domains/foodprepguide.com/shop-monitor.sh <domain.tld>
#    bash /home/nginx/domains/foodprepguide.com/shop-monitor.sh remove <domain.tld>

set -euo pipefail

die() { echo "ERROR: $*" >&2; exit 1; }

ACTION="install"
DOMAIN=""
if [[ $# -eq 1 ]]; then
  DOMAIN="$1"
elif [[ $# -eq 2 && "$1" == "remove" ]]; then
  ACTION="remove"
  DOMAIN="$2"
else
  cat >&2 <<USAGE
Usage:
  $0 <domain.tld>
  $0 remove <domain.tld>
USAGE
  exit 1
fi

# ---- Derived paths/names
UNIT_NAME_BASE="$(echo "${DOMAIN}-shop-monitor" | tr '.' '-')"
UNIT_NAME="${UNIT_NAME_BASE}.service"
ROOT="/home/nginx/domains/${DOMAIN}"
WP_PATH="${ROOT}/public"
WORKER="${ROOT}/shop-monitor-worker.sh"
LOG_DIR="${ROOT}/logs"
STATE_FILE="/var/run/shop-monitor.${DOMAIN}.lastfix"
UNIT_FILE="/etc/systemd/system/${UNIT_NAME}"

if [[ "$ACTION" == "remove" ]]; then
  systemctl stop "$UNIT_NAME" 2>/dev/null || true
  systemctl disable "$UNIT_NAME" 2>/dev/null || true
  rm -f "$UNIT_FILE"
  systemctl daemon-reload
  echo "Removed ${UNIT_NAME}."
  exit 0
fi

# ---- Install
[[ -d "$ROOT" ]] || die "Domain root not found: $ROOT"
mkdir -p "$LOG_DIR"
touch "$STATE_FILE" || true

# Per-domain worker (does the monitoring + flush)
cat > "$WORKER" <<'EOF'
#!/bin/bash
set -o nounset
set -o pipefail

DOMAIN="__DOMAIN__"
URL="https://__DOMAIN__/shop/"
WP_PATH="__WP_PATH__"
STATE_FILE="__STATE_FILE__"
COOLDOWN_SECONDS=600
CHECK_INTERVAL=5

serverip=$(ip route get 1 | awk '{print $NF;exit}')

send_slack_alert() {
  local message="$1"
  bash /bigscoots/general/slack.sh "#woo-errors" ":warning: \n*Hostname:* $(hostname)\n *Server IP:* ${serverip}\n *Message:* ${message}"
}

mkdir -p "$(dirname "$STATE_FILE")"

while true; do
  TMPFILE=$(mktemp)
  # -L follows redirects, --compressed handles gzip
  HTTP_STATUS=$(curl -sS -L --compressed --max-time 10 \
    -H "Accept: text/html;q=1.0,*/*;q=0.8" \
    -H "User-Agent: shop-monitor/1.0 (+bigscoots)" \
    -w "%{http_code}" -o "$TMPFILE" "$URL" || echo "000")

  # Count Woo product tiles
  PRODUCT_COUNT=$(grep -Eio 'class="[^"]*\btype-product\b[^"]*"' "$TMPFILE" | wc -l | awk '{print $1}')

  echo "$(date '+%F %T') domain=${DOMAIN} status=$HTTP_STATUS products=$PRODUCT_COUNT"

  # TRIGGER LOGIC: 404 error OR (200 OK but 0 products)
  TRIGGER_FIX=false
  REASON=""

  if [[ "$HTTP_STATUS" == "404" ]]; then
    TRIGGER_FIX=true
    REASON="Page returned 404 Not Found"
  elif [[ "$HTTP_STATUS" == "200" && "$PRODUCT_COUNT" -eq 0 ]]; then
    TRIGGER_FIX=true
    REASON="Page returned 200 OK but 0 'type-product' entries"
  fi

  if [ "$TRIGGER_FIX" = true ]; then
    now_epoch=$(date +%s)
    last_fix=0
    [[ -f "$STATE_FILE" ]] && last_fix=$(cat "$STATE_FILE" 2>/dev/null || echo 0)
    since=$(( now_epoch - last_fix ))

    if (( since >= COOLDOWN_SECONDS )); then
      TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
      msg="[${TIMESTAMP}] ${URL} issue detected: ${REASON}. Running 'wp rewrite flush --hard'."
      echo "$msg" >> "__LOG_DIR__/shop-monitor.log"
      send_slack_alert "$msg"

      # Diagnostics
      cp -rf "$TMPFILE" "__LOG_DIR__/shop-monitor-capture-${TIMESTAMP}.html"
      wp rewrite list --allow-root --path="$WP_PATH" > "__LOG_DIR__/shop-monitor-rewrites-${TIMESTAMP}.log" 2>&1
      
      # The Fix
      wp rewrite flush --hard --allow-root --path="$WP_PATH"
      wp cache flush --allow-root --path="$WP_PATH" 2>/dev/null || true
      if wp plugin is-active bigscoots-cache --quiet  --path="$WP_PATH" 2>/dev/null; then
        wp bs_cache purge_cache  --path="$WP_PATH" 2>/dev/null
      fi

      echo "$now_epoch" > "$STATE_FILE"
    else
      echo "Cooldown active (${since}s < ${COOLDOWN_SECONDS}s); skipping flush."
    fi
  fi

  rm -f "$TMPFILE"
  sleep "$CHECK_INTERVAL"
done
EOF

# Fill in template vars in the worker
sed -i \
  -e "s#__DOMAIN__#${DOMAIN}#g" \
  -e "s#__WP_PATH__#${WP_PATH}#g" \
  -e "s#__STATE_FILE__#${STATE_FILE}#g" \
  -e "s#__LOG_DIR__#${LOG_DIR}#g" \
  "$WORKER"

chmod +x "$WORKER"

# systemd unit
cat > "$UNIT_FILE" <<EOF
[Unit]
Description=Monitor ${DOMAIN} shop page for missing products or 404s and flush permalinks
After=network.target

[Service]
Type=simple
ExecStart=${WORKER}
Restart=always
RestartSec=3
User=root
StandardOutput=append:${LOG_DIR}/shop-monitor.service.log
StandardError=append:${LOG_DIR}/shop-monitor.service.err

[Install]
WantedBy=multi-user.target
EOF

# Reload + enable + start
systemctl daemon-reload
systemctl enable --now "$UNIT_NAME"

echo "Installed and started ${UNIT_NAME}"
systemctl --no-pager --lines=20 status "$UNIT_NAME" || true