README – Visitor Snapshot & Tracking System
<article class="markdown-body">
# Visitor Snapshot & Tracking System (PHP 8.3)
מערכת PHP קלה לשילוב בכל אתר, המאפשרת:
- 📸 צילום תמונה (snapshot) מהמצלמה של המשתמש (בהסכמה בלבד)
- 📍 קבלת מיקום (GPS) ושמירתו
- 🌍 שמירת IP + מדינה (דרך פונקציית geocoding)
- 🧑💻 אזור אדמין לצפייה בזמן אמת בכל המשתמשים והצילומים
- ⏱ Rate limit – צילום אחד לכל משתמש כל 30 דקות
- 🖼 גלריית תמונות לכל משתמש באדמין
נבנה עבור PHP **8.3** + MySQL / MariaDB, ומיועד להטמעה מהירה בכל אתר קיים.
---
## 📁 מבנה כללי של הפרויקט
מומלץ מבנה (ניתן לשנות לפי הצורך):
```text
project-root/
├─ public/
│ ├─ capture.js
│ ├─ user_heartbeat.php
│ ├─ save_snapshot.php
│ ├─ snapshot_bootstrap.php
│ └─ uploads/ # התמונות וה־JSON נשמרים כאן
│
├─ admin/
│ ├─ login.php
│ ├─ dashboard.php
│ ├─ create_admin.php
│ ├─ api_users.php
│ ├─ api_user_details.php
│ ├─ api_user_gallery.php
│ ├─ api_request_snapshot.php
│ └─ api_logs.php
│
└─ README.md
```
> בפועל אפשר למקם את הקבצים איך שנוח, העיקר לעדכן את הנתיבים בקוד.
---
## 🛢 בסיס נתונים (MySQL)
### 1. טבלת אדמין – `admin_users`
```sql
CREATE TABLE IF NOT EXISTS admin_users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 2. טבלת צילומים – `snapshot_events`
```sql
CREATE TABLE IF NOT EXISTS snapshot_events (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
snapshot_id VARCHAR(32) NOT NULL,
user_numeric_id BIGINT UNSIGNED NOT NULL,
folder_name VARCHAR(100) NOT NULL,
file_name VARCHAR(255) NOT NULL,
image_url VARCHAR(255) NOT NULL,
device_type VARCHAR(20) NOT NULL,
latitude DECIMAL(10,7) NULL,
longitude DECIMAL(10,7) NULL,
accuracy FLOAT NULL,
country_code VARCHAR(2) NULL,
country_name VARCHAR(100) NULL,
ip VARCHAR(45) NULL,
user_agent TEXT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_time (user_numeric_id, created_at),
INDEX idx_ip_time (ip, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 3. טבלת משתמשים "חיים" – `tracked_users`
```sql
CREATE TABLE IF NOT EXISTS tracked_users (
user_numeric_id BIGINT UNSIGNED PRIMARY KEY,
first_seen DATETIME NOT NULL,
last_seen DATETIME NOT NULL,
last_latitude DECIMAL(10,7) NULL,
last_longitude DECIMAL(10,7) NULL,
last_accuracy FLOAT NULL,
last_device_type VARCHAR(20) NOT NULL,
last_ip VARCHAR(45) NULL,
last_country_code VARCHAR(2) NULL,
last_country_name VARCHAR(100) NULL,
consent_given TINYINT(1) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 4. טבלת בקשות צילום מרחוק – `snapshot_requests`
```sql
CREATE TABLE IF NOT EXISTS snapshot_requests (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_numeric_id BIGINT UNSIGNED NOT NULL,
requested_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
processed_at DATETIME NULL,
status ENUM('pending','processed','failed') NOT NULL DEFAULT 'pending',
admin_id INT UNSIGNED NULL,
INDEX idx_user_status (user_numeric_id, status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
---
## ⚙️ קובצי קונפיגורציה
בכל קובץ PHP שמתחבר ל־DB (למשל `save_snapshot.php`, `user_heartbeat.php`, קבצי API באדמין וכו’) יש לעדכן:
```php
$dbHost = 'localhost';
$dbName = 'your_database_name';
$dbUser = 'your_db_user';
$dbPass = 'your_db_password';
$dsn = "mysql:host={$dbHost};dbname={$dbName};charset=utf8mb4";
```
בנוסף, ב־`save_snapshot.php` יש:
```php
$publicBaseUrl = 'https://your-domain.com'; // לעדכן לדומיין האמיתי שלך
```
---
## 👨💻 יצירת משתמש אדמין ראשון
קובץ `admin/create_admin.php` מאפשר ליצור משתמש אדמין דרך דפדפן.
1. העלה את `create_admin.php` ל־`admin/`.
2. גש לכתובת:
```text
https://your-domain.com/admin/create_admin.php
```
3. מלא שם משתמש + סיסמה (לפחות 8 תווים).
4. לאחר יצירת המשתמש – **מומלץ מאוד**:
- למחוק את הקובץ `create_admin.php`, או
- להגביל אליו גישה לפי IP / .htaccess.
---
## 🔐 אזור אדמין – מה יש שם?
הכניסה מתבצעת דרך:
```text
https://your-domain.com/admin/login.php
```
לאחר התחברות תגיע ל־`dashboard.php`:
- רשימת משתמשים (לפי `tracked_users`)
- פרטי משתמש נבחר (IP, מיקום, מדינה, זמן אחרון)
- כפתור **"בקש צילום עכשיו"** – שולח בקשה מרחוק למשתמש
- גלריית תמונות לכל משתמש (מושכות מ־`snapshot_events`)
- לוג ריאלטיים (list של הצילומים האחרונים)
ה־UI משתמש ב־HTML + CSS בסיסי, בלי ספריות חיצוניות – קל להתאמה.
---
## 🌐 שילוב המערכת בכל אתר (require_once)
כדי לחבר את המערכת לכל עמוד באתר שלך, עושים:
1. ודא שהקבצים `capture.js`, `user_heartbeat.php`, `save_snapshot.php` ו־`snapshot_bootstrap.php` נמצאים בתיקיה נגישה (למשל `/public`).
2. בתוך כל עמוד PHP שבו אתה רוצה:
- להציג את UI ההסכמה
- להפעיל מצלמה/מיקום
- להתחבר למערכת
הוסף (בתחילת ה־HTML, לפני ``):
```php
```
### דוגמת `snapshot_bootstrap.php` (רעיון כללי)
```php
time() + 60 * 60 * 24 * 365 * 2,
'path' => '/',
'secure' => isset($_SERVER['HTTPS']),
'httponly' => false,
'samesite' => 'Lax',
]
);
return $userId;
}
$userNumericId = getOrCreateUserNumericId();
?>
<script>
// להעביר את user_numeric_id ל-JS
window.SNAPSHOT_USER_ID = ;
</script>
<script src="/public/capture.js"></script>
> אפשר לעצב את UI ההסכמה (מודאל / באנר) בכל דרך שרוצים – העיקר שהמשתמש רואה בבירור מה נאסף ומה המטרה.
---
## 🧠 מה המערכת עושה בפועל?
### בצד המשתמש
1. המשתמש נכנס לאתר → המערכת יוצרת לו `user_numeric_id` (קוקי).
2. אם הוא נותן הסכמה:
- המצלמה מופעלת (`getUserMedia`)
- מיקום מבוקש (`navigator.geolocation`)
3. כפתור/פעולה בצד המשתמש שולח:
- תמונה (Base64) → `save_snapshot.php`
- מיקום + User-Agent
4. `capture.js` שולח **heartbeat** ל־`user_heartbeat.php` כל כמה שניות:
- מעדכן מיקום/מצב ב־`tracked_users`
- בודק אם יש בקשה לצילום (`snapshot_requests`)
### בצד השרת
- `save_snapshot.php`:
- מוודא Rate Limit (פעם ב־30 דקות לכל משתמש)
- שומר קובץ תמונה תחת `uploads/deviceType.YYYY-MM-DD/snapshot_<id>.jpg`
- בונה URL ציבורי לתמונה ושומר ב־DB
- שומר לוג ב־`snapshot_events`
- `user_heartbeat.php`:
- מעדכן `tracked_users`
- בודק אם קיימת בקשת צילום ממתינה ב־`snapshot_requests`
- אם יש – מחזיר ל־JS `take_snapshot = true` → בצד לקוח מתבצעת `autoCaptureAndSend()`
- אזור אדמין:
- מציג משתמשים חיים
- מציג גלריית צילומים לכל משתמש
- מאפשר לבקש צילום נוסף
---
## 🔒 אבטחה ופרטיות – הערות חשובות
- **חובה לעבוד ב־HTTPS**:
- מצלמה + GPS לא יעבדו ברוב הדפדפנים ללא HTTPS.
- **חובה להציג הסכמה ברורה**:
- להסביר למשתמש מה נאסף (תמונה, מיקום, IP), למה, ולאיזה מטרה.
- **מומלץ לעדכן מדיניות פרטיות**:
- כמה זמן שומרים את המידע
- מי ניגש אליו
- **create_admin.php**:
- להשתמש בו רק ליצירת אדמין
- למחוק / לחסום גישה אחרי השימוש
- **Rate Limit**:
- כבר מיושם (ברירת מחדל: צילום אחד לכל משתמש כל 30 דקות), ניתן לשנות בקוד.
---
## 🚀 רעיונות להרחבה
- חיבור geocoding אמיתי (GeoIP / ip-api וכו’) בפונקציה `resolveCountry()`.
- הוספת מפה (Leaflet / Mapbox) בדשבורד להצגת המשתמשים על מפה.
- הוספת WebSocket / SSE ללוגים במקום polling.
- הפיכת המערכת ל־WordPress Plugin עם עמודי הגדרות בלוח הבקרה.
---
נבנה ונועד להרחבה – אפשר להשתמש בזה כבסיס ל־KYC, צ’ק־אין פיזי, בקרת גישה, logging אבטחה ועוד.
</code></pre>
</article>
</div>
</body>
</html>