Compare commits
6 commits
5ab180b5d0
...
6bb957d772
| Author | SHA1 | Date | |
|---|---|---|---|
| 6bb957d772 | |||
| f92ea45286 | |||
| 2a06bb1f15 | |||
| f66f1494c5 | |||
| aebfb9adb8 | |||
| 80f11e71dd |
16 changed files with 634 additions and 213 deletions
|
|
@ -2,67 +2,44 @@
|
||||||
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"mcp__playwright__browser_click",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -100 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log | grep -i -E ''(fatal|error|warning|dashboard|manage)''\")",
|
||||||
"Bash(wp eval:*)",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp plugin list | grep -E ''(events-calendar|tribe)''\")",
|
||||||
"Bash(test:*)",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp plugin deactivate the-events-calendar-community-events\")",
|
||||||
"mcp__playwright__browser_take_screenshot",
|
"Bash(printf:*)",
|
||||||
"Bash(chmod:*)",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no benr@146.190.76.204 \"tail -100 /home/974670.cloudwaysapps.com/ncjzsayvsk/public_html/wp-content/debug.log | grep -i -E ''(security|nonce|edit|6288)''\")",
|
||||||
"Bash(bin/refresh-user-roles-capabilities.sh:*)",
|
"Bash(scripts/deploy.sh:*)",
|
||||||
"Bash(find:*)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/includes/class-hvac-trainer-communication-templates.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/includes/)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/templates/page-edit-event.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/templates/)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/refresh-roles-capabilities-local.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp eval-file wp-content/plugins/hvac-community-events/refresh-roles-capabilities-local.php\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user list --field=user_login\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user get test_admin --field=roles\")",
|
|
||||||
"mcp__playwright__browser_type",
|
|
||||||
"Bash(echo:*)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/includes/class-hvac-announcements-admin.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/includes/)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/templates/page-master-announcements.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/templates/)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/assets/css/hvac-announcements-admin.css roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/assets/css/)",
|
|
||||||
"Bash(git log:*)",
|
|
||||||
"mcp__zen__thinkdeep",
|
|
||||||
"mcp__zen__testgen",
|
|
||||||
"Bash(git add:*)",
|
|
||||||
"Bash(git commit:*)",
|
|
||||||
"Bash(curl:*)",
|
|
||||||
"Bash(node:*)",
|
|
||||||
"mcp__playwright__browser_navigate",
|
"mcp__playwright__browser_navigate",
|
||||||
"mcp__playwright__browser_wait_for",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user list --role=hvac_master_trainer --fields=user_login,user_email --format=table\")",
|
||||||
"mcp__zen__analyze",
|
"mcp__playwright__browser_type",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp --path=/home/974670.cloudwaysapps.com/uberrxmprk/public_html user get test_trainer --field=roles\")",
|
"mcp__playwright__browser_click",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -20 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log\")",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user update joe@upskillhvac.com --user_pass=''JoeTest123!'' --skip-email\")",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp plugin list | grep -E ''community|event''\")",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user list --role=hvac_trainer --fields=user_login,user_email --format=table | head -5\")",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user get test_trainer --field=roles\")",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -50 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log | grep -i -E ''(master-trainer|trainers|javascript|enqueue)''\")",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user update test_trainer --user_pass=trainer123\")",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user get test_master --field=roles\")",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/assets/js/hvac-rest-api-event-submission.js roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/assets/js/)",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user create test_master_new test.master.new@example.com --role=hvac_master_trainer --user_pass=''TestNew123!'' --skip-email 2>&1 || wp user update test_master_new --user_pass=''TestNew123!'' --skip-email\")",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/templates/template-hvac-master-dashboard.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/templates/)",
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user list --field=user_login | grep test\")",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && which composer && composer --version\")",
|
||||||
|
"Bash(unzip:*)",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp plugin list | grep -E ''(wordpress-mcp|Name)''\")",
|
||||||
|
"WebFetch(domain:github.com)",
|
||||||
|
"WebFetch(domain:json.schemastore.org)",
|
||||||
|
"WebFetch(domain:www.schemastore.org)",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass:*)",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /tmp/wordpress-mcp.zip roodev@146.190.76.204:/tmp/wordpress-mcp-prod.zip)",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/ncjzsayvsk/public_html && wp plugin install /tmp/wordpress-mcp-prod.zip --activate\")",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no benr@146.190.76.204 \"ls -la /home/974670.cloudwaysapps.com/ | head -20\")",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cat /home/974670.cloudwaysapps.com/ncjzsayvsk/public_html/wp-config.php 2>&1 | grep -i ''site.*url'' | head -5 || echo ''Checking domain...''\")",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y@1oVkz0M\" sshpass -e ssh -o StrictHostKeyChecking=no benr@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/ncjzsayvsk/public_html && wp plugin install /tmp/wordpress-mcp-prod.zip --activate\")",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y@1oVkz0M\" sshpass -e ssh -o StrictHostKeyChecking=no benr@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/ncjzsayvsk/public_html && wp plugin list | grep -E ''(wordpress-mcp|Name)''\")",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user update master_trainer --user_pass=''MasterTest123!'' --skip-email 2>&1 || echo ''User does not exist, creating...'' && wp user create master_trainer master_trainer@example.com --role=hvac_master_trainer --user_pass=''MasterTest123!'' --skip-email\")",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp plugin list | grep -E ''(security|login|limit)''\")",
|
||||||
|
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp post list --post_type=page --s=''announcements'' --fields=ID,post_title,post_name,post_status --format=table\")",
|
||||||
|
"mcp__zen__codereview",
|
||||||
"mcp__playwright__browser_console_messages",
|
"mcp__playwright__browser_console_messages",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -50 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log\")",
|
|
||||||
"mcp__zen__debug",
|
"mcp__zen__debug",
|
||||||
"mcp__playwright__browser_evaluate",
|
"mcp__playwright__browser_evaluate",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user update test_master --user_pass=master123\")",
|
"mcp__playwright__browser_take_screenshot",
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user update test_master --user_pass=MasterTrainer2024!\")",
|
"mcp__playwright__browser_wait_for"
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/templates/page-master-trainers.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/templates/)",
|
|
||||||
"WebFetch(domain:upskill-staging.measurequick.com)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user get test_trainer --field=capabilities\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/includes/class-hvac-plugin.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/includes/)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e scp -o StrictHostKeyChecking=no /home/ben/dev/upskill-event-manager/includes/class-hvac-ajax-handlers.php roodev@146.190.76.204:/home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/hvac-community-events/includes/)",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -100 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log | grep -i -E ''(TEC|Security|tribe|filter|hook)''\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -200 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log | grep -E ''(HVAC TEC|TEC Integration|TEC Debug)''\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp plugin list | grep -E ''event|tribe|community''\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"find /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/the-events-calendar-community-events -name ''*.php'' -exec grep -l ''do_action.*submit\\|apply_filters.*submit'' {} \\;\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"grep -n -A5 -B5 ''do_action.*submit\\|apply_filters.*submit'' /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/the-events-calendar-community-events/src/Tribe/Main.php\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"find /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/the-events-calendar-community-events -name ''*.php'' -exec grep -l ''submission.*handler\\|form.*submit\\|event.*save'' {} \\;\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"grep -n -A20 -B5 ''do_action\\|apply_filters'' /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/plugins/the-events-calendar-community-events/src/Events_Community/Submission/Save.php\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp option get tribe_events_community_options | grep -E ''communityRewriteSlug|eventsDefaultStatus''\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp post list --post_type=tribe_events --posts_per_page=5 --format=table\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp post create --post_type=tribe_events --post_title=''Test Hook Integration'' --post_content=''Testing TEC hook integration'' --post_excerpt=''Test excerpt for hook validation'' --post_status=publish --format=ids\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"tail -30 /home/974670.cloudwaysapps.com/uberrxmprk/public_html/wp-content/debug.log\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp plugin get the-events-calendar-community-events --field=status\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp rewrite list | grep -i community\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user set-role devadmin administrator\")",
|
|
||||||
"Bash(SSHPASS=\"uSCO6f1y\" sshpass -e ssh -o StrictHostKeyChecking=no roodev@146.190.76.204 \"cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp user set-role ben@measurequick.com administrator\")"
|
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": [],
|
"ask": [],
|
||||||
|
|
@ -70,5 +47,9 @@
|
||||||
"/tmp"
|
"/tmp"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"enableAllProjectMcpServers": true
|
"enableAllProjectMcpServers": true,
|
||||||
}
|
"disabledMcpjsonServers": [
|
||||||
|
"postgres",
|
||||||
|
"kubernetes"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -220,6 +220,7 @@ coverage/
|
||||||
!.claude/agents/
|
!.claude/agents/
|
||||||
!.claude/agents/*.md
|
!.claude/agents/*.md
|
||||||
!CLAUDE.md
|
!CLAUDE.md
|
||||||
|
.mcp.json # MCP configuration contains JWT tokens
|
||||||
|
|
||||||
# Forgejo Actions CI/CD
|
# Forgejo Actions CI/CD
|
||||||
!.forgejo/
|
!.forgejo/
|
||||||
|
|
|
||||||
27
CLAUDE.md
27
CLAUDE.md
|
|
@ -44,6 +44,33 @@ node test-comprehensive-validation.js
|
||||||
```bash
|
```bash
|
||||||
wp rewrite flush
|
wp rewrite flush
|
||||||
wp eval 'HVAC_Page_Manager::create_required_pages();'
|
wp eval 'HVAC_Page_Manager::create_required_pages();'
|
||||||
|
|
||||||
|
# Reset user password (when wp user update fails with password hashing)
|
||||||
|
wp eval 'wp_set_password("YourPassword123", USER_ID);'
|
||||||
|
|
||||||
|
# Example for test_master user (ID: 25 on staging)
|
||||||
|
wp eval 'wp_set_password("TestPass123", 25);'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Credentials (Staging)
|
||||||
|
```bash
|
||||||
|
# Master Trainer Test Account
|
||||||
|
Username: test_master
|
||||||
|
Password: TestPass123
|
||||||
|
User ID: 25
|
||||||
|
Role: hvac_master_trainer
|
||||||
|
|
||||||
|
# Password Reset Method (if login fails after wp user update)
|
||||||
|
# SSH to staging server:
|
||||||
|
ssh roodev@146.190.76.204
|
||||||
|
|
||||||
|
# Navigate to WordPress root and reset password:
|
||||||
|
cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html
|
||||||
|
wp eval 'wp_set_password("TestPass123", 25);'
|
||||||
|
|
||||||
|
# Why wp_set_password instead of wp user update:
|
||||||
|
# wp user update --user_pass sometimes has password hashing issues
|
||||||
|
# wp_set_password properly hashes the password using wp_hash_password()
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🎯 Core Development Principles
|
## 🎯 Core Development Principles
|
||||||
|
|
|
||||||
|
|
@ -171,12 +171,17 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
z-index: 999999;
|
z-index: 100000; /* Below WordPress media modal (160000) to allow media library to stack on top */
|
||||||
display: flex;
|
display: none; /* Hidden by default to prevent FOUC */
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Modal active state - shown by JavaScript */
|
||||||
|
.hvac-modal.active {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
background: white;
|
background: white;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
|
|
|
||||||
|
|
@ -789,50 +789,7 @@ body.modal-open {
|
||||||
color: #666;
|
color: #666;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
/* Duplicate modal styles removed - using .active class approach at lines 168-187 */
|
||||||
/* Modal Styles */
|
|
||||||
.hvac-modal {
|
|
||||||
display: none;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 999999;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
background-color: rgba(0, 0, 0, 0.6);
|
|
||||||
animation: fadeIn 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from { opacity: 0; }
|
|
||||||
to { opacity: 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.hvac-modal .modal-content {
|
|
||||||
background-color: #fefefe;
|
|
||||||
margin: 40px auto;
|
|
||||||
padding: 0;
|
|
||||||
border-radius: 8px;
|
|
||||||
width: 90%;
|
|
||||||
max-width: 900px;
|
|
||||||
max-height: 90vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
box-shadow: 0 5px 30px rgba(0, 0, 0, 0.3);
|
|
||||||
position: relative;
|
|
||||||
animation: slideIn 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideIn {
|
|
||||||
from {
|
|
||||||
transform: translateY(-30px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translateY(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hvac-modal .modal-close {
|
.hvac-modal .modal-close {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ jQuery(document).ready(function($) {
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
init();
|
init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the announcements interface
|
* Initialize the announcements interface
|
||||||
*/
|
*/
|
||||||
|
|
@ -24,27 +24,8 @@ jQuery(document).ready(function($) {
|
||||||
loadAnnouncements();
|
loadAnnouncements();
|
||||||
loadCategories();
|
loadCategories();
|
||||||
initializeEventHandlers();
|
initializeEventHandlers();
|
||||||
initializeEditor();
|
// NOTE: Editor initialization removed - wp_editor() PHP function handles this
|
||||||
}
|
// The duplicate JavaScript initialization was causing the media modal to auto-open
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize TinyMCE editor
|
|
||||||
*/
|
|
||||||
function initializeEditor() {
|
|
||||||
if (typeof wp !== 'undefined' && wp.editor) {
|
|
||||||
// Initialize WordPress editor
|
|
||||||
wp.editor.initialize('announcement-content', {
|
|
||||||
tinymce: {
|
|
||||||
wpautop: true,
|
|
||||||
plugins: 'lists link image media paste',
|
|
||||||
toolbar1: 'formatselect | bold italic | alignleft aligncenter alignright | bullist numlist | link unlink | wp_adv',
|
|
||||||
toolbar2: 'strikethrough hr forecolor pastetext removeformat charmap outdent indent undo redo wp_help',
|
|
||||||
height: 300
|
|
||||||
},
|
|
||||||
quicktags: true,
|
|
||||||
mediaButtons: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -251,8 +232,14 @@ jQuery(document).ready(function($) {
|
||||||
* Open the modal for adding/editing
|
* Open the modal for adding/editing
|
||||||
*/
|
*/
|
||||||
function openModal(announcementId) {
|
function openModal(announcementId) {
|
||||||
$('#announcement-modal').fadeIn();
|
const $modal = $('#announcement-modal');
|
||||||
|
$modal.addClass('active');
|
||||||
|
$('body').addClass('modal-open');
|
||||||
|
|
||||||
|
// Add custom "Add Media" button to TinyMCE editor toolbar
|
||||||
|
// This is needed because media_buttons => false in wp_editor() to prevent auto-open
|
||||||
|
addMediaButtonToEditor();
|
||||||
|
|
||||||
if (announcementId) {
|
if (announcementId) {
|
||||||
$('#modal-title').text('Edit Announcement');
|
$('#modal-title').text('Edit Announcement');
|
||||||
loadAnnouncementForEdit(announcementId);
|
loadAnnouncementForEdit(announcementId);
|
||||||
|
|
@ -261,12 +248,80 @@ jQuery(document).ready(function($) {
|
||||||
resetForm();
|
resetForm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add custom "Add Media" button to TinyMCE editor
|
||||||
|
* Required because wp_editor has media_buttons => false to prevent auto-open in hidden modal
|
||||||
|
*/
|
||||||
|
function addMediaButtonToEditor() {
|
||||||
|
// Check if button already exists
|
||||||
|
if ($('#wp-announcement-content-media-buttons').length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create media button container
|
||||||
|
const $mediaButton = $('<div id="wp-announcement-content-media-buttons" class="wp-media-buttons"></div>');
|
||||||
|
const $addMediaBtn = $('<button type="button" id="insert-media-button" class="button insert-media add_media" data-editor="announcement-content"></button>');
|
||||||
|
$addMediaBtn.html('<span class="wp-media-buttons-icon"></span> Add Media');
|
||||||
|
|
||||||
|
// Add click handler
|
||||||
|
$addMediaBtn.on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
openEditorMediaUploader();
|
||||||
|
});
|
||||||
|
|
||||||
|
$mediaButton.append($addMediaBtn);
|
||||||
|
|
||||||
|
// Insert button before editor wrapper
|
||||||
|
$('#wp-announcement-content-wrap').before($mediaButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open media uploader for the announcement content editor
|
||||||
|
*/
|
||||||
|
function openEditorMediaUploader() {
|
||||||
|
if (typeof wp.media === 'undefined') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const editorMediaUploader = wp.media({
|
||||||
|
title: 'Insert Media',
|
||||||
|
button: {
|
||||||
|
text: 'Insert into post'
|
||||||
|
},
|
||||||
|
multiple: true
|
||||||
|
});
|
||||||
|
|
||||||
|
editorMediaUploader.on('select', function() {
|
||||||
|
const selection = editorMediaUploader.state().get('selection');
|
||||||
|
const editor = tinymce.get('announcement-content');
|
||||||
|
|
||||||
|
selection.forEach(function(attachment) {
|
||||||
|
attachment = attachment.toJSON();
|
||||||
|
let html = '';
|
||||||
|
|
||||||
|
if (attachment.type === 'image') {
|
||||||
|
html = '<img src="' + attachment.url + '" alt="' + (attachment.alt || '') + '" />';
|
||||||
|
} else {
|
||||||
|
html = '<a href="' + attachment.url + '">' + attachment.title + '</a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (editor) {
|
||||||
|
editor.insertContent(html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
editorMediaUploader.open();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the modal
|
* Close the modal
|
||||||
*/
|
*/
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
$('#announcement-modal').fadeOut();
|
const $modal = $('#announcement-modal');
|
||||||
|
$modal.removeClass('active');
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
resetForm();
|
resetForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -276,15 +331,18 @@ jQuery(document).ready(function($) {
|
||||||
function resetForm() {
|
function resetForm() {
|
||||||
$('#announcement-form')[0].reset();
|
$('#announcement-form')[0].reset();
|
||||||
$('#announcement-id').val('');
|
$('#announcement-id').val('');
|
||||||
|
|
||||||
// Reset editor
|
// Reset editor using TinyMCE native API
|
||||||
if (wp.editor) {
|
if (typeof tinymce !== 'undefined') {
|
||||||
wp.editor.setContent('announcement-content', '');
|
const editor = tinymce.get('announcement-content');
|
||||||
|
if (editor) {
|
||||||
|
editor.setContent('');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset featured image
|
// Reset featured image
|
||||||
removeFeaturedImage();
|
removeFeaturedImage();
|
||||||
|
|
||||||
// Uncheck all categories
|
// Uncheck all categories
|
||||||
$('#categories-container input[type="checkbox"]').prop('checked', false);
|
$('#categories-container input[type="checkbox"]').prop('checked', false);
|
||||||
}
|
}
|
||||||
|
|
@ -316,26 +374,29 @@ jQuery(document).ready(function($) {
|
||||||
$('#announcement-excerpt').val(announcement.excerpt);
|
$('#announcement-excerpt').val(announcement.excerpt);
|
||||||
$('#announcement-status').val(announcement.status);
|
$('#announcement-status').val(announcement.status);
|
||||||
$('#announcement-tags').val(announcement.tags);
|
$('#announcement-tags').val(announcement.tags);
|
||||||
|
|
||||||
// Set content in editor
|
// Set content in editor using TinyMCE native API
|
||||||
if (wp.editor) {
|
if (typeof tinymce !== 'undefined') {
|
||||||
wp.editor.setContent('announcement-content', announcement.content);
|
const editor = tinymce.get('announcement-content');
|
||||||
|
if (editor) {
|
||||||
|
editor.setContent(announcement.content || '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set publish date
|
// Set publish date
|
||||||
if (announcement.date) {
|
if (announcement.date) {
|
||||||
const date = new Date(announcement.date);
|
const date = new Date(announcement.date);
|
||||||
const localDate = date.toISOString().slice(0, 16);
|
const localDate = date.toISOString().slice(0, 16);
|
||||||
$('#announcement-date').val(localDate);
|
$('#announcement-date').val(localDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set categories
|
// Set categories
|
||||||
if (announcement.categories && announcement.categories.length > 0) {
|
if (announcement.categories && announcement.categories.length > 0) {
|
||||||
announcement.categories.forEach(function(catId) {
|
announcement.categories.forEach(function(catId) {
|
||||||
$('#categories-container input[value="' + catId + '"]').prop('checked', true);
|
$('#categories-container input[value="' + catId + '"]').prop('checked', true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set featured image
|
// Set featured image
|
||||||
if (announcement.featured_image_id) {
|
if (announcement.featured_image_id) {
|
||||||
$('#featured-image-id').val(announcement.featured_image_id);
|
$('#featured-image-id').val(announcement.featured_image_id);
|
||||||
|
|
@ -350,12 +411,19 @@ jQuery(document).ready(function($) {
|
||||||
* Save announcement (create or update)
|
* Save announcement (create or update)
|
||||||
*/
|
*/
|
||||||
function saveAnnouncement() {
|
function saveAnnouncement() {
|
||||||
// Get editor content
|
// Get editor content using WordPress editor API or TinyMCE native API
|
||||||
let content = '';
|
let content = '';
|
||||||
if (wp.editor) {
|
if (typeof wp !== 'undefined' && wp.editor && wp.editor.getContent) {
|
||||||
|
// Use WordPress API if available (WordPress 4.8+)
|
||||||
content = wp.editor.getContent('announcement-content');
|
content = wp.editor.getContent('announcement-content');
|
||||||
|
} else if (typeof tinymce !== 'undefined') {
|
||||||
|
// Fallback to TinyMCE native API
|
||||||
|
const editor = tinymce.get('announcement-content');
|
||||||
|
if (editor) {
|
||||||
|
content = editor.getContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather form data
|
// Gather form data
|
||||||
const formData = {
|
const formData = {
|
||||||
action: $('#announcement-id').val() ? 'hvac_update_announcement' : 'hvac_create_announcement',
|
action: $('#announcement-id').val() ? 'hvac_update_announcement' : 'hvac_create_announcement',
|
||||||
|
|
@ -370,12 +438,12 @@ jQuery(document).ready(function($) {
|
||||||
categories: [],
|
categories: [],
|
||||||
featured_image_id: $('#featured-image-id').val()
|
featured_image_id: $('#featured-image-id').val()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get selected categories
|
// Get selected categories
|
||||||
$('#categories-container input:checked').each(function() {
|
$('#categories-container input:checked').each(function() {
|
||||||
formData.categories.push($(this).val());
|
formData.categories.push($(this).val());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send AJAX request
|
// Send AJAX request
|
||||||
$.post(hvac_announcements.ajax_url, formData, function(response) {
|
$.post(hvac_announcements.ajax_url, formData, function(response) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
|
|
|
||||||
156
assets/js/hvac-master-trainers-overview.js
Normal file
156
assets/js/hvac-master-trainers-overview.js
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
/**
|
||||||
|
* Master Trainers Overview JavaScript
|
||||||
|
* Handles AJAX loading of trainer data and filtering
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Wait for DOM and dependencies
|
||||||
|
$(document).ready(function() {
|
||||||
|
console.log('[HVAC] Master Trainers Overview: Initializing...');
|
||||||
|
|
||||||
|
// Check if we're on the trainers page
|
||||||
|
if ($('#hvac-master-trainers-overview').length === 0) {
|
||||||
|
console.log('[HVAC] Master Trainers Overview: Not on trainers page, skipping initialization');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('[HVAC] Master Trainers Overview: Found trainers container, loading data...');
|
||||||
|
|
||||||
|
// Load initial stats
|
||||||
|
loadTrainerStats();
|
||||||
|
|
||||||
|
// Load initial trainers list
|
||||||
|
loadTrainersList();
|
||||||
|
|
||||||
|
// Handle filter changes
|
||||||
|
$('#hvac-trainers-filters').on('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
loadTrainersList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle filter changes on select/input
|
||||||
|
$('#filter-status, #filter-region, #filter-search').on('change keyup', debounce(function() {
|
||||||
|
loadTrainersList();
|
||||||
|
}, 500));
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load trainer statistics
|
||||||
|
*/
|
||||||
|
function loadTrainerStats() {
|
||||||
|
console.log('[HVAC] Loading trainer stats...');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: hvac_master_trainers_ajax.ajax_url,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'hvac_master_trainers_stats',
|
||||||
|
nonce: hvac_master_trainers_ajax.nonce
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
console.log('[HVAC] Stats loaded successfully', response);
|
||||||
|
|
||||||
|
if (response.success && response.data.html) {
|
||||||
|
$('#hvac-stats-tiles').html(response.data.html).show();
|
||||||
|
$('#hvac-stats-loading').hide();
|
||||||
|
} else {
|
||||||
|
console.error('[HVAC] Stats load failed:', response);
|
||||||
|
$('#hvac-stats-loading').html('<p class="hvac-error">Failed to load statistics.</p>');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error('[HVAC] Stats AJAX error:', status, error);
|
||||||
|
$('#hvac-stats-loading').html('<p class="hvac-error">Error loading statistics.</p>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load trainers list with current filters
|
||||||
|
*/
|
||||||
|
function loadTrainersList() {
|
||||||
|
console.log('[HVAC] Loading trainers list...');
|
||||||
|
|
||||||
|
// Show loading state
|
||||||
|
$('#hvac-trainers-loading').show();
|
||||||
|
$('#hvac-trainers-table-container').hide();
|
||||||
|
|
||||||
|
// Get filter values
|
||||||
|
var filters = {
|
||||||
|
action: 'hvac_master_trainers_filter',
|
||||||
|
nonce: hvac_master_trainers_ajax.nonce,
|
||||||
|
status: $('#filter-status').val() || 'all',
|
||||||
|
region: $('#filter-region').val() || '',
|
||||||
|
search: $('#filter-search').val() || ''
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('[HVAC] Filter values:', filters);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: hvac_master_trainers_ajax.ajax_url,
|
||||||
|
type: 'POST',
|
||||||
|
data: filters,
|
||||||
|
success: function(response) {
|
||||||
|
console.log('[HVAC] Trainers loaded successfully', response);
|
||||||
|
|
||||||
|
if (response.success && response.data.html) {
|
||||||
|
$('#hvac-trainers-table-container').html(response.data.html).show();
|
||||||
|
$('#hvac-trainers-loading').hide();
|
||||||
|
|
||||||
|
// Initialize any interactive elements in the table
|
||||||
|
initializeTrainerActions();
|
||||||
|
} else {
|
||||||
|
console.error('[HVAC] Trainers load failed:', response);
|
||||||
|
$('#hvac-trainers-loading').html('<p class="hvac-error">Failed to load trainers.</p>');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error('[HVAC] Trainers AJAX error:', status, error);
|
||||||
|
$('#hvac-trainers-loading').html('<p class="hvac-error">Error loading trainers.</p>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize trainer action buttons
|
||||||
|
*/
|
||||||
|
function initializeTrainerActions() {
|
||||||
|
console.log('[HVAC] Initializing trainer actions...');
|
||||||
|
|
||||||
|
// Handle view profile buttons
|
||||||
|
$('.hvac-view-trainer').on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var trainerId = $(this).data('trainer-id');
|
||||||
|
console.log('[HVAC] View trainer:', trainerId);
|
||||||
|
// Navigate to trainer profile
|
||||||
|
window.location.href = $(this).attr('href');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle edit buttons
|
||||||
|
$('.hvac-edit-trainer').on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var trainerId = $(this).data('trainer-id');
|
||||||
|
console.log('[HVAC] Edit trainer:', trainerId);
|
||||||
|
window.location.href = $(this).attr('href');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Any other interactive elements...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debounce function for search input
|
||||||
|
*/
|
||||||
|
function debounce(func, wait) {
|
||||||
|
var timeout;
|
||||||
|
return function() {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(function() {
|
||||||
|
func.apply(context, args);
|
||||||
|
}, wait);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
})(jQuery);
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
* Plugin Name: HVAC Community Events
|
* Plugin Name: HVAC Community Events
|
||||||
* Plugin URI: https://upskillhvac.com
|
* Plugin URI: https://upskillhvac.com
|
||||||
* Description: Custom plugin for HVAC trainer event management system
|
* Description: Custom plugin for HVAC trainer event management system
|
||||||
* Version: 2.0.0
|
* Version: 2.1.7
|
||||||
* Author: Upskill HVAC
|
* Author: Upskill HVAC
|
||||||
* Author URI: https://upskillhvac.com
|
* Author URI: https://upskillhvac.com
|
||||||
* License: GPL-2.0+
|
* License: GPL-2.0+
|
||||||
|
|
|
||||||
|
|
@ -40,35 +40,60 @@ class HVAC_Announcements_Admin {
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
private function __construct() {
|
private function __construct() {
|
||||||
|
HVAC_Logger::log('Constructor called - initializing hooks', 'Announcements Admin');
|
||||||
$this->init_hooks();
|
$this->init_hooks();
|
||||||
|
HVAC_Logger::log('Hooks initialized successfully', 'Announcements Admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize hooks
|
* Initialize hooks
|
||||||
*/
|
*/
|
||||||
private function init_hooks() {
|
private function init_hooks() {
|
||||||
add_action('wp_enqueue_scripts', array($this, 'enqueue_admin_assets'));
|
HVAC_Logger::log('Registering wp_enqueue_scripts hook with priority 20', 'Announcements Admin');
|
||||||
|
// Use priority 20 to ensure post object is available
|
||||||
|
add_action('wp_enqueue_scripts', array($this, 'enqueue_admin_assets'), 20);
|
||||||
|
HVAC_Logger::log('Hook registered successfully', 'Announcements Admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueue admin assets on master trainer pages
|
* Enqueue admin assets on master trainer pages
|
||||||
*/
|
*/
|
||||||
public function enqueue_admin_assets() {
|
public function enqueue_admin_assets() {
|
||||||
|
HVAC_Logger::log('enqueue_admin_assets called', 'Announcements Admin');
|
||||||
|
HVAC_Logger::log('is_master_trainer = ' . (HVAC_Announcements_Permissions::is_master_trainer() ? 'YES' : 'NO'), 'Announcements Admin');
|
||||||
|
HVAC_Logger::log('is_page_template check = ' . (is_page_template('page-master-announcements.php') ? 'YES' : 'NO'), 'Announcements Admin');
|
||||||
|
|
||||||
|
$queried = get_queried_object();
|
||||||
|
if ($queried) {
|
||||||
|
HVAC_Logger::log('queried_object type = ' . get_class($queried), 'Announcements Admin');
|
||||||
|
if (is_a($queried, 'WP_Post')) {
|
||||||
|
HVAC_Logger::log('post_name = ' . $queried->post_name, 'Announcements Admin');
|
||||||
|
HVAC_Logger::log('post_type = ' . $queried->post_type, 'Announcements Admin');
|
||||||
|
$template = get_post_meta($queried->ID, '_wp_page_template', true);
|
||||||
|
HVAC_Logger::log('page_template meta = ' . $template, 'Announcements Admin');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only enqueue on master trainer announcement pages
|
// Only enqueue on master trainer announcement pages
|
||||||
if ($this->is_master_trainer_announcement_page()) {
|
if ($this->is_master_trainer_announcement_page()) {
|
||||||
// Enqueue admin JavaScript
|
HVAC_Logger::log('ENQUEUING SCRIPTS', 'Announcements Admin');
|
||||||
|
|
||||||
|
// Enqueue editor - dependencies handled automatically
|
||||||
|
wp_enqueue_editor();
|
||||||
|
|
||||||
|
// Enqueue admin JavaScript - Load in footer after wp_editor inline scripts
|
||||||
wp_enqueue_script(
|
wp_enqueue_script(
|
||||||
'hvac-announcements-admin',
|
'hvac-announcements-admin',
|
||||||
plugin_dir_url(dirname(__FILE__)) . 'assets/js/hvac-announcements-admin.js',
|
plugin_dir_url(dirname(__FILE__)) . 'assets/js/hvac-announcements-admin.js',
|
||||||
array('jquery', 'wp-editor'),
|
array('jquery', 'editor'),
|
||||||
defined('HVAC_VERSION') ? HVAC_VERSION : '1.0.0',
|
defined('HVAC_VERSION') ? HVAC_VERSION : '1.0.0',
|
||||||
true
|
true // Load in footer after wp_editor inline scripts
|
||||||
);
|
);
|
||||||
|
|
||||||
// Localize script with AJAX data
|
// Localize script with AJAX data
|
||||||
wp_localize_script('hvac-announcements-admin', 'hvac_announcements', array(
|
wp_localize_script('hvac-announcements-admin', 'hvac_announcements', array(
|
||||||
'ajax_url' => admin_url('admin-ajax.php'),
|
'ajax_url' => admin_url('admin-ajax.php'),
|
||||||
'nonce' => wp_create_nonce('hvac_announcements_admin_nonce'),
|
'nonce' => wp_create_nonce('hvac_announcements_nonce'),
|
||||||
'strings' => array(
|
'strings' => array(
|
||||||
'confirm_delete' => __('Are you sure you want to delete this announcement?', 'hvac'),
|
'confirm_delete' => __('Are you sure you want to delete this announcement?', 'hvac'),
|
||||||
'error_loading' => __('Error loading announcements.', 'hvac'),
|
'error_loading' => __('Error loading announcements.', 'hvac'),
|
||||||
|
|
@ -93,27 +118,56 @@ class HVAC_Announcements_Admin {
|
||||||
/**
|
/**
|
||||||
* Check if current page is master trainer announcement page
|
* Check if current page is master trainer announcement page
|
||||||
*
|
*
|
||||||
|
* Uses multi-layered detection approach for reliability during wp_enqueue_scripts
|
||||||
|
* @see class-hvac-scripts-styles.php for pattern reference
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function is_master_trainer_announcement_page() {
|
private function is_master_trainer_announcement_page() {
|
||||||
global $post;
|
// Check if user is master trainer first
|
||||||
|
|
||||||
if (!is_a($post, 'WP_Post')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if user is master trainer
|
|
||||||
if (!HVAC_Announcements_Permissions::is_master_trainer()) {
|
if (!HVAC_Announcements_Permissions::is_master_trainer()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for announcement pages
|
// PRIMARY: Check URL path (most reliable during wp_enqueue_scripts)
|
||||||
$announcement_slugs = array(
|
$current_path = isset($_SERVER['REQUEST_URI']) ? trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/') : '';
|
||||||
'master-announcements',
|
|
||||||
'master-manage-announcements'
|
$announcement_paths = array(
|
||||||
|
'master-trainer/announcements',
|
||||||
|
'master-trainer/master-announcements',
|
||||||
|
'master-trainer/manage-announcements'
|
||||||
);
|
);
|
||||||
|
|
||||||
return in_array($post->post_name, $announcement_slugs);
|
foreach ($announcement_paths as $path) {
|
||||||
|
if (strpos($current_path, $path) !== false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SECONDARY: Check page template (may not work during wp_enqueue_scripts)
|
||||||
|
if (is_page_template('page-master-announcements.php')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TERTIARY: Check by page slug
|
||||||
|
if (is_page('announcements') || is_page('master-announcements') || is_page('manage-announcements')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FALLBACK: Check queried object for announcement slugs
|
||||||
|
$queried_object = get_queried_object();
|
||||||
|
if (is_a($queried_object, 'WP_Post')) {
|
||||||
|
$announcement_slugs = array(
|
||||||
|
'announcements',
|
||||||
|
'master-announcements',
|
||||||
|
'master-manage-announcements',
|
||||||
|
'manage-announcements'
|
||||||
|
);
|
||||||
|
|
||||||
|
return in_array($queried_object->post_name, $announcement_slugs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -184,7 +238,7 @@ class HVAC_Announcements_Admin {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Announcement Modal -->
|
<!-- Announcement Modal -->
|
||||||
<div id="announcement-modal" class="hvac-modal" style="display: none;">
|
<div id="announcement-modal" class="hvac-modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h2 id="modal-title"><?php _e('Add New Announcement', 'hvac'); ?></h2>
|
<h2 id="modal-title"><?php _e('Add New Announcement', 'hvac'); ?></h2>
|
||||||
|
|
@ -206,9 +260,11 @@ class HVAC_Announcements_Admin {
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="announcement-content"><?php _e('Content', 'hvac'); ?> <span class="required">*</span></label>
|
<label for="announcement-content"><?php _e('Content', 'hvac'); ?> <span class="required">*</span></label>
|
||||||
<?php
|
<?php
|
||||||
|
// CRITICAL: media_buttons => false to prevent auto-open in hidden modal
|
||||||
|
// Media button will be added manually via JavaScript when modal opens
|
||||||
wp_editor('', 'announcement-content', array(
|
wp_editor('', 'announcement-content', array(
|
||||||
'textarea_name' => 'announcement_content',
|
'textarea_name' => 'announcement_content',
|
||||||
'media_buttons' => true,
|
'media_buttons' => false, // FIXED: Prevents media modal auto-open in hidden div
|
||||||
'textarea_rows' => 10,
|
'textarea_rows' => 10,
|
||||||
'teeny' => false,
|
'teeny' => false,
|
||||||
'dfw' => false,
|
'dfw' => false,
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ class HVAC_Announcements_Display {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal for viewing announcement -->
|
<!-- Modal for viewing announcement -->
|
||||||
<div id="announcement-modal" class="hvac-modal" style="display: none;">
|
<div id="announcement-modal" class="hvac-modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<span class="modal-close">×</span>
|
<span class="modal-close">×</span>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
@ -251,7 +251,7 @@ class HVAC_Announcements_Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
$atts = shortcode_atts(array(
|
$atts = shortcode_atts(array(
|
||||||
'url' => 'https://drive.google.com/drive/folders/16uDRkFcaEqKUxfBek9VbfbAIeFV77nZG?usp=drive_link',
|
'url' => 'https://drive.google.com/drive/folders/1-SDHGR9Ix6BmUVTHa3wI99K0rwfWL-vs?usp=drive_link',
|
||||||
'height' => '600',
|
'height' => '600',
|
||||||
'width' => '100%',
|
'width' => '100%',
|
||||||
), $atts);
|
), $atts);
|
||||||
|
|
|
||||||
|
|
@ -43,18 +43,23 @@ class HVAC_Dashboard_Data {
|
||||||
*/
|
*/
|
||||||
public function get_total_events_count() {
|
public function get_total_events_count() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Check if TEC is available
|
||||||
|
if ( ! class_exists( 'Tribe__Events__Main' ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Cache key based on user ID
|
// Cache key based on user ID
|
||||||
$cache_key = 'hvac_dashboard_total_events_' . $this->user_id;
|
$cache_key = 'hvac_dashboard_total_events_' . $this->user_id;
|
||||||
$count = wp_cache_get( $cache_key, 'hvac_dashboard' );
|
$count = wp_cache_get( $cache_key, 'hvac_dashboard' );
|
||||||
|
|
||||||
if ( false === $count ) {
|
if ( false === $count ) {
|
||||||
// Use direct database query to avoid TEC query hijacking
|
// Use direct database query to avoid TEC query hijacking
|
||||||
$count = $wpdb->get_var( $wpdb->prepare(
|
$count = $wpdb->get_var( $wpdb->prepare(
|
||||||
"SELECT COUNT(*) FROM {$wpdb->posts}
|
"SELECT COUNT(*) FROM {$wpdb->posts}
|
||||||
WHERE post_type = %s
|
WHERE post_type = %s
|
||||||
AND post_author = %d
|
AND post_author = %d
|
||||||
AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
|
AND post_status IN ('publish', 'future', 'draft', 'pending', 'private')",
|
||||||
Tribe__Events__Main::POSTTYPE,
|
Tribe__Events__Main::POSTTYPE,
|
||||||
$this->user_id
|
$this->user_id
|
||||||
|
|
@ -84,20 +89,25 @@ class HVAC_Dashboard_Data {
|
||||||
*/
|
*/
|
||||||
public function get_upcoming_events_count() {
|
public function get_upcoming_events_count() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
|
// Check if TEC is available
|
||||||
|
if ( ! class_exists( 'Tribe__Events__Main' ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Cache key based on user ID
|
// Cache key based on user ID
|
||||||
$cache_key = 'hvac_dashboard_upcoming_events_' . $this->user_id;
|
$cache_key = 'hvac_dashboard_upcoming_events_' . $this->user_id;
|
||||||
$count = wp_cache_get( $cache_key, 'hvac_dashboard' );
|
$count = wp_cache_get( $cache_key, 'hvac_dashboard' );
|
||||||
|
|
||||||
if ( false === $count ) {
|
if ( false === $count ) {
|
||||||
$today = date( 'Y-m-d H:i:s' );
|
$today = date( 'Y-m-d H:i:s' );
|
||||||
|
|
||||||
// Use direct database query to avoid TEC query hijacking
|
// Use direct database query to avoid TEC query hijacking
|
||||||
$count = $wpdb->get_var( $wpdb->prepare(
|
$count = $wpdb->get_var( $wpdb->prepare(
|
||||||
"SELECT COUNT(*) FROM {$wpdb->posts} p
|
"SELECT COUNT(*) FROM {$wpdb->posts} p
|
||||||
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_EventStartDate'
|
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_EventStartDate'
|
||||||
WHERE p.post_type = %s
|
WHERE p.post_type = %s
|
||||||
AND p.post_author = %d
|
AND p.post_author = %d
|
||||||
AND p.post_status IN ('publish', 'future')
|
AND p.post_status IN ('publish', 'future')
|
||||||
AND (pm.meta_value >= %s OR pm.meta_value IS NULL)",
|
AND (pm.meta_value >= %s OR pm.meta_value IS NULL)",
|
||||||
Tribe__Events__Main::POSTTYPE,
|
Tribe__Events__Main::POSTTYPE,
|
||||||
|
|
@ -119,20 +129,25 @@ class HVAC_Dashboard_Data {
|
||||||
*/
|
*/
|
||||||
public function get_past_events_count() {
|
public function get_past_events_count() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
|
// Check if TEC is available
|
||||||
|
if ( ! class_exists( 'Tribe__Events__Main' ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Cache key based on user ID
|
// Cache key based on user ID
|
||||||
$cache_key = 'hvac_dashboard_past_events_' . $this->user_id;
|
$cache_key = 'hvac_dashboard_past_events_' . $this->user_id;
|
||||||
$count = wp_cache_get( $cache_key, 'hvac_dashboard' );
|
$count = wp_cache_get( $cache_key, 'hvac_dashboard' );
|
||||||
|
|
||||||
if ( false === $count ) {
|
if ( false === $count ) {
|
||||||
$today = date( 'Y-m-d H:i:s' );
|
$today = date( 'Y-m-d H:i:s' );
|
||||||
|
|
||||||
// Use direct database query to avoid TEC query hijacking
|
// Use direct database query to avoid TEC query hijacking
|
||||||
$count = $wpdb->get_var( $wpdb->prepare(
|
$count = $wpdb->get_var( $wpdb->prepare(
|
||||||
"SELECT COUNT(*) FROM {$wpdb->posts} p
|
"SELECT COUNT(*) FROM {$wpdb->posts} p
|
||||||
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_EventEndDate'
|
LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_EventEndDate'
|
||||||
WHERE p.post_type = %s
|
WHERE p.post_type = %s
|
||||||
AND p.post_author = %d
|
AND p.post_author = %d
|
||||||
AND p.post_status IN ('publish', 'private')
|
AND p.post_status IN ('publish', 'private')
|
||||||
AND pm.meta_value < %s",
|
AND pm.meta_value < %s",
|
||||||
Tribe__Events__Main::POSTTYPE,
|
Tribe__Events__Main::POSTTYPE,
|
||||||
|
|
|
||||||
|
|
@ -76,12 +76,71 @@ class HVAC_Master_Trainers_Overview {
|
||||||
// AJAX handlers for trainers overview
|
// AJAX handlers for trainers overview
|
||||||
add_action( 'wp_ajax_hvac_master_trainers_filter', array( $this, 'ajax_filter_trainers' ) );
|
add_action( 'wp_ajax_hvac_master_trainers_filter', array( $this, 'ajax_filter_trainers' ) );
|
||||||
add_action( 'wp_ajax_hvac_master_trainers_stats', array( $this, 'ajax_get_stats' ) );
|
add_action( 'wp_ajax_hvac_master_trainers_stats', array( $this, 'ajax_get_stats' ) );
|
||||||
|
|
||||||
// Shortcode for embedding trainers overview
|
// Shortcode for embedding trainers overview
|
||||||
add_shortcode( 'hvac_master_trainers', array( $this, 'render_trainers_overview' ) );
|
add_shortcode( 'hvac_master_trainers', array( $this, 'render_trainers_overview' ) );
|
||||||
|
|
||||||
// Add function for template integration
|
// Add function for template integration
|
||||||
add_action( 'init', array( $this, 'register_template_functions' ) );
|
add_action( 'init', array( $this, 'register_template_functions' ) );
|
||||||
|
|
||||||
|
// Enqueue scripts for master trainers overview
|
||||||
|
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue scripts for master trainers overview
|
||||||
|
*/
|
||||||
|
public function enqueue_scripts() {
|
||||||
|
// Only enqueue on master trainers pages
|
||||||
|
if ( ! is_page() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
global $post;
|
||||||
|
if ( ! $post ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is the master trainers page
|
||||||
|
$is_trainers_page = false;
|
||||||
|
|
||||||
|
// Check 1: Post content contains the shortcode
|
||||||
|
if ( strpos( $post->post_content, '[hvac_master_trainers]' ) !== false ) {
|
||||||
|
$is_trainers_page = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check 2: Template slug matches
|
||||||
|
$template = get_page_template_slug( $post->ID );
|
||||||
|
if ( $template === 'page-master-trainers.php' ) {
|
||||||
|
$is_trainers_page = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check 3: Page slug matches (most reliable)
|
||||||
|
if ( $post->post_name === 'trainers' && strpos( $_SERVER['REQUEST_URI'], '/master-trainer/trainers' ) !== false ) {
|
||||||
|
$is_trainers_page = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $is_trainers_page ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_enqueue_script(
|
||||||
|
'hvac-master-trainers-overview',
|
||||||
|
HVAC_PLUGIN_URL . 'assets/js/hvac-master-trainers-overview.js',
|
||||||
|
array( 'jquery' ),
|
||||||
|
HVAC_VERSION,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
// Localize script with AJAX data
|
||||||
|
wp_localize_script(
|
||||||
|
'hvac-master-trainers-overview',
|
||||||
|
'hvac_master_trainers_ajax',
|
||||||
|
array(
|
||||||
|
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||||
|
'nonce' => wp_create_nonce( 'hvac_master_trainers_nonce' )
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -235,7 +294,7 @@ class HVAC_Master_Trainers_Overview {
|
||||||
*/
|
*/
|
||||||
public function ajax_filter_trainers() {
|
public function ajax_filter_trainers() {
|
||||||
// Verify nonce
|
// Verify nonce
|
||||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'hvac_master_trainers_nonce' ) ) {
|
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'hvac_master_trainers_nonce' ) ) {
|
||||||
wp_send_json_error( array( 'message' => 'Security check failed' ) );
|
wp_send_json_error( array( 'message' => 'Security check failed' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,12 +317,75 @@ class HVAC_Master_Trainers_Overview {
|
||||||
// Get trainers data
|
// Get trainers data
|
||||||
if ( $this->dashboard_data ) {
|
if ( $this->dashboard_data ) {
|
||||||
$trainer_stats = $this->dashboard_data->get_trainer_statistics();
|
$trainer_stats = $this->dashboard_data->get_trainer_statistics();
|
||||||
|
|
||||||
// Format trainers for display
|
// Format trainers for display
|
||||||
$formatted_trainers = $this->format_trainers_for_display( $trainer_stats['trainer_data'], $args );
|
$formatted_trainers = $this->format_trainers_for_display( $trainer_stats['trainer_data'], $args );
|
||||||
|
|
||||||
|
// Generate HTML table
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
<table class="hvac-trainers-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Location</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Total Events</th>
|
||||||
|
<th>Registered</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if ( empty( $formatted_trainers ) ) : ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="7" class="hvac-no-results">No trainers found matching your criteria.</td>
|
||||||
|
</tr>
|
||||||
|
<?php else : ?>
|
||||||
|
<?php foreach ( $formatted_trainers as $trainer ) : ?>
|
||||||
|
<tr>
|
||||||
|
<td class="hvac-trainer-name">
|
||||||
|
<strong><?php echo esc_html( $trainer['name'] ); ?></strong>
|
||||||
|
</td>
|
||||||
|
<td class="hvac-trainer-email">
|
||||||
|
<a href="mailto:<?php echo esc_attr( $trainer['email'] ); ?>">
|
||||||
|
<?php echo esc_html( $trainer['email'] ); ?>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="hvac-trainer-location">
|
||||||
|
<?php echo esc_html( $trainer['location'] ); ?>
|
||||||
|
</td>
|
||||||
|
<td class="hvac-trainer-status">
|
||||||
|
<span class="hvac-status-badge <?php echo esc_attr( $trainer['status_class'] ); ?>">
|
||||||
|
<?php echo esc_html( $trainer['status'] ); ?>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="hvac-trainer-events">
|
||||||
|
<?php echo esc_html( $trainer['total_events'] ); ?>
|
||||||
|
</td>
|
||||||
|
<td class="hvac-trainer-registered">
|
||||||
|
<?php echo esc_html( $trainer['registered'] ); ?>
|
||||||
|
</td>
|
||||||
|
<td class="hvac-trainer-actions">
|
||||||
|
<a href="<?php echo esc_url( $trainer['profile_link'] ); ?>"
|
||||||
|
class="hvac-btn hvac-btn-sm hvac-btn-primary hvac-view-trainer"
|
||||||
|
data-trainer-id="<?php echo esc_attr( $trainer['id'] ); ?>">
|
||||||
|
View Profile
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="hvac-trainers-count">
|
||||||
|
Showing <?php echo esc_html( count( $formatted_trainers ) ); ?> trainer(s)
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
$html = ob_get_clean();
|
||||||
|
|
||||||
wp_send_json_success( array(
|
wp_send_json_success( array(
|
||||||
'trainers' => $formatted_trainers,
|
'html' => $html,
|
||||||
'total_found' => count( $formatted_trainers )
|
'total_found' => count( $formatted_trainers )
|
||||||
) );
|
) );
|
||||||
}
|
}
|
||||||
|
|
@ -276,7 +398,7 @@ class HVAC_Master_Trainers_Overview {
|
||||||
*/
|
*/
|
||||||
public function ajax_get_stats() {
|
public function ajax_get_stats() {
|
||||||
// Verify nonce
|
// Verify nonce
|
||||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'hvac_master_trainers_nonce' ) ) {
|
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'hvac_master_trainers_nonce' ) ) {
|
||||||
wp_send_json_error( array( 'message' => 'Security check failed' ) );
|
wp_send_json_error( array( 'message' => 'Security check failed' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,7 +409,7 @@ class HVAC_Master_Trainers_Overview {
|
||||||
|
|
||||||
if ( $this->dashboard_data ) {
|
if ( $this->dashboard_data ) {
|
||||||
$trainer_stats = $this->dashboard_data->get_trainer_statistics();
|
$trainer_stats = $this->dashboard_data->get_trainer_statistics();
|
||||||
|
|
||||||
$stats = array(
|
$stats = array(
|
||||||
'total_trainers' => $trainer_stats['total_trainers'],
|
'total_trainers' => $trainer_stats['total_trainers'],
|
||||||
'active_trainers' => $this->count_trainers_by_status( 'active' ),
|
'active_trainers' => $this->count_trainers_by_status( 'active' ),
|
||||||
|
|
@ -296,7 +418,33 @@ class HVAC_Master_Trainers_Overview {
|
||||||
'total_revenue' => $trainer_stats['total_revenue']
|
'total_revenue' => $trainer_stats['total_revenue']
|
||||||
);
|
);
|
||||||
|
|
||||||
wp_send_json_success( $stats );
|
// Generate HTML for stats tiles
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
<div class="hvac-stat-tile">
|
||||||
|
<div class="hvac-stat-value"><?php echo esc_html( number_format( $stats['total_trainers'] ) ); ?></div>
|
||||||
|
<div class="hvac-stat-label">Total Trainers</div>
|
||||||
|
</div>
|
||||||
|
<div class="hvac-stat-tile">
|
||||||
|
<div class="hvac-stat-value"><?php echo esc_html( number_format( $stats['active_trainers'] ) ); ?></div>
|
||||||
|
<div class="hvac-stat-label">Active Trainers</div>
|
||||||
|
</div>
|
||||||
|
<div class="hvac-stat-tile">
|
||||||
|
<div class="hvac-stat-value"><?php echo esc_html( number_format( $stats['pending_trainers'] ) ); ?></div>
|
||||||
|
<div class="hvac-stat-label">Pending Approval</div>
|
||||||
|
</div>
|
||||||
|
<div class="hvac-stat-tile">
|
||||||
|
<div class="hvac-stat-value"><?php echo esc_html( number_format( $stats['total_events'] ) ); ?></div>
|
||||||
|
<div class="hvac-stat-label">Total Events</div>
|
||||||
|
</div>
|
||||||
|
<div class="hvac-stat-tile">
|
||||||
|
<div class="hvac-stat-value">$<?php echo esc_html( number_format( $stats['total_revenue'], 2 ) ); ?></div>
|
||||||
|
<div class="hvac-stat-label">Total Revenue</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
$html = ob_get_clean();
|
||||||
|
|
||||||
|
wp_send_json_success( array( 'html' => $html ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
wp_send_json_error( array( 'message' => 'Unable to load trainer stats' ) );
|
wp_send_json_error( array( 'message' => 'Unable to load trainer stats' ) );
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ final class HVAC_Plugin {
|
||||||
define('HVAC_PLUGIN_VERSION', '2.0.0');
|
define('HVAC_PLUGIN_VERSION', '2.0.0');
|
||||||
}
|
}
|
||||||
if (!defined('HVAC_VERSION')) {
|
if (!defined('HVAC_VERSION')) {
|
||||||
define('HVAC_VERSION', '2.0.0');
|
define('HVAC_VERSION', '2.1.7');
|
||||||
}
|
}
|
||||||
if (!defined('HVAC_PLUGIN_FILE')) {
|
if (!defined('HVAC_PLUGIN_FILE')) {
|
||||||
define('HVAC_PLUGIN_FILE', dirname(__DIR__) . '/hvac-community-events.php');
|
define('HVAC_PLUGIN_FILE', dirname(__DIR__) . '/hvac-community-events.php');
|
||||||
|
|
@ -238,6 +238,7 @@ final class HVAC_Plugin {
|
||||||
'class-hvac-master-events-overview.php',
|
'class-hvac-master-events-overview.php',
|
||||||
'class-hvac-master-trainers-overview.php',
|
'class-hvac-master-trainers-overview.php',
|
||||||
'class-hvac-announcements-manager.php',
|
'class-hvac-announcements-manager.php',
|
||||||
|
'class-hvac-announcements-admin.php',
|
||||||
'class-hvac-announcements-display.php',
|
'class-hvac-announcements-display.php',
|
||||||
'class-hvac-master-pages-fixer.php',
|
'class-hvac-master-pages-fixer.php',
|
||||||
'class-hvac-master-layout-standardizer.php',
|
'class-hvac-master-layout-standardizer.php',
|
||||||
|
|
@ -545,7 +546,8 @@ final class HVAC_Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule non-critical components for lazy loading
|
// Schedule non-critical components for lazy loading
|
||||||
add_action('wp_loaded', [$this, 'initializeSecondaryComponents'], 5);
|
// Use 'init' instead of 'wp_loaded' so components can register wp_enqueue_scripts hooks
|
||||||
|
add_action('init', [$this, 'initializeSecondaryComponents'], 5);
|
||||||
add_action('admin_init', [$this, 'initializeAdminComponents'], 5);
|
add_action('admin_init', [$this, 'initializeAdminComponents'], 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -712,8 +714,13 @@ final class HVAC_Plugin {
|
||||||
if (class_exists('HVAC_Announcements_Display')) {
|
if (class_exists('HVAC_Announcements_Display')) {
|
||||||
HVAC_Announcements_Display::get_instance();
|
HVAC_Announcements_Display::get_instance();
|
||||||
}
|
}
|
||||||
|
error_log('HVAC Plugin: Checking if HVAC_Announcements_Admin class exists: ' . (class_exists('HVAC_Announcements_Admin') ? 'YES' : 'NO'));
|
||||||
if (class_exists('HVAC_Announcements_Admin')) {
|
if (class_exists('HVAC_Announcements_Admin')) {
|
||||||
|
error_log('HVAC Plugin: Instantiating HVAC_Announcements_Admin...');
|
||||||
HVAC_Announcements_Admin::get_instance();
|
HVAC_Announcements_Admin::get_instance();
|
||||||
|
error_log('HVAC Plugin: HVAC_Announcements_Admin instantiated successfully');
|
||||||
|
} else {
|
||||||
|
error_log('HVAC Plugin: ERROR - HVAC_Announcements_Admin class does not exist!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ get_header();
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<form method="post" action="" class="hvac-event-form" novalidate>
|
<form method="post" action="" class="hvac-event-form" novalidate>
|
||||||
<?php wp_nonce_field('hvac_edit_event', 'hvac_event_nonce'); ?>
|
<?php wp_nonce_field('hvac_event_action', 'hvac_event_nonce'); ?>
|
||||||
<input type="hidden" name="event_id" value="<?php echo esc_attr($event_id); ?>">
|
<input type="hidden" name="event_id" value="<?php echo esc_attr($event_id); ?>">
|
||||||
|
|
||||||
<!-- Basic Information -->
|
<!-- Basic Information -->
|
||||||
|
|
|
||||||
|
|
@ -172,8 +172,8 @@ $menu_system = HVAC_Menu_System::get_instance();
|
||||||
<div class="google-drive-container">
|
<div class="google-drive-container">
|
||||||
<?php
|
<?php
|
||||||
// Google Drive embed with proper URL format
|
// Google Drive embed with proper URL format
|
||||||
$drive_url = 'https://drive.google.com/drive/folders/16uDRkFcaEqKUxfBek9VbfbAIeFV77nZG?usp=drive_link';
|
$drive_url = 'https://drive.google.com/drive/folders/1-SDHGR9Ix6BmUVTHa3wI99K0rwfWL-vs?usp=drive_link';
|
||||||
$folder_id = '16uDRkFcaEqKUxfBek9VbfbAIeFV77nZG';
|
$folder_id = '1-SDHGR9Ix6BmUVTHa3wI99K0rwfWL-vs';
|
||||||
|
|
||||||
// Use the modern embed format that works better
|
// Use the modern embed format that works better
|
||||||
$embed_url = 'https://drive.google.com/embeddedfolderview?id=' . $folder_id;
|
$embed_url = 'https://drive.google.com/embeddedfolderview?id=' . $folder_id;
|
||||||
|
|
|
||||||
|
|
@ -160,13 +160,13 @@ class Test_HVAC_Announcements_Display extends WP_UnitTestCase {
|
||||||
*/
|
*/
|
||||||
public function test_google_drive_shortcode() {
|
public function test_google_drive_shortcode() {
|
||||||
wp_set_current_user( $this->regular_trainer );
|
wp_set_current_user( $this->regular_trainer );
|
||||||
|
|
||||||
$output = do_shortcode( '[hvac_google_drive_embed url="https://drive.google.com/drive/folders/16uDRkFcaEqKUxfBek9VbfbAIeFV77nZG" height="500"]' );
|
$output = do_shortcode( '[hvac_google_drive_embed url="https://drive.google.com/drive/folders/1-SDHGR9Ix6BmUVTHa3wI99K0rwfWL-vs" height="500"]' );
|
||||||
|
|
||||||
// Should contain iframe
|
// Should contain iframe
|
||||||
$this->assertStringContainsString( '<iframe', $output );
|
$this->assertStringContainsString( '<iframe', $output );
|
||||||
$this->assertStringContainsString( 'height="500"', $output );
|
$this->assertStringContainsString( 'height="500"', $output );
|
||||||
|
|
||||||
// Should contain embed URL
|
// Should contain embed URL
|
||||||
$this->assertStringContainsString( 'embeddedfolderview', $output );
|
$this->assertStringContainsString( 'embeddedfolderview', $output );
|
||||||
}
|
}
|
||||||
|
|
@ -178,17 +178,17 @@ class Test_HVAC_Announcements_Display extends WP_UnitTestCase {
|
||||||
$reflection = new ReflectionClass( $this->display_handler );
|
$reflection = new ReflectionClass( $this->display_handler );
|
||||||
$method = $reflection->getMethod( 'convert_drive_url_to_embed' );
|
$method = $reflection->getMethod( 'convert_drive_url_to_embed' );
|
||||||
$method->setAccessible( true );
|
$method->setAccessible( true );
|
||||||
|
|
||||||
// Test folder URL conversion
|
// Test folder URL conversion
|
||||||
$sharing_url = 'https://drive.google.com/drive/folders/16uDRkFcaEqKUxfBek9VbfbAIeFV77nZG?usp=drive_link';
|
$sharing_url = 'https://drive.google.com/drive/folders/1-SDHGR9Ix6BmUVTHa3wI99K0rwfWL-vs?usp=drive_link';
|
||||||
$embed_url = $method->invoke( $this->display_handler, $sharing_url );
|
$embed_url = $method->invoke( $this->display_handler, $sharing_url );
|
||||||
|
|
||||||
$this->assertEquals( 'https://drive.google.com/embeddedfolderview?id=16uDRkFcaEqKUxfBek9VbfbAIeFV77nZG#list', $embed_url );
|
$this->assertEquals( 'https://drive.google.com/embeddedfolderview?id=1-SDHGR9Ix6BmUVTHa3wI99K0rwfWL-vs#list', $embed_url );
|
||||||
|
|
||||||
// Test invalid URL returns original
|
// Test invalid URL returns original
|
||||||
$invalid_url = 'https://example.com/not-a-drive-url';
|
$invalid_url = 'https://example.com/not-a-drive-url';
|
||||||
$result = $method->invoke( $this->display_handler, $invalid_url );
|
$result = $method->invoke( $this->display_handler, $invalid_url );
|
||||||
|
|
||||||
$this->assertEquals( $invalid_url, $result );
|
$this->assertEquals( $invalid_url, $result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue