הדף מתאר את זרימת העבודה כפי שהיא היום: איפה כותבים קוד, איך הקוד מגיע לשרת, ומה קורה אחר כך באתרי הלקוחות. חלק מהזרימה פנימי ל-Wizzo (פריסה לשרת ה-master), וחלק פתוח לכל מפתח (אתר מקומי ו-PR). הדף מפריד ביניהם במפורש, ובסוף מראה מה המפה המומלצת לפיתוח חיצוני.
system/ בדף הזה הוא תיקיית הליבה הפרוסה באתר, ו-api/core/ היא אותה תיקייה בריפו. {admin} הוא CONFIG::$admin_url.
התמונה הכללית#
הליבה היא תיקייה אחת של קבצי PHP. אין שלב build: אין קומפילציה, אין minify מראש ואין composer install שמורץ על ידי הריפו. "בנייה" פירושה העתקת קבצים.
ריפו wizzo50_core master (אתר Wizzo) אתרי הלקוחות
───────────────── ────────────────── ─────────────
api/core/ ──העלאה (FTP/SFTP)──► <site>/system/core ◄──עדכון גרסה── {admin}/wizzo_update/get
api/js/ ──העלאה──────────────► <site>/system/js (הורדת ZIP של הליבה מה-master)
- ריפו הליבה (
wizzo-products/wizzo50_core):api/core/הוא הליבה,api/js/ארבעה קבצי JS משותפים. מבנה מלא ב-מבנה הריפו. - ה-master: אתר אחד של Wizzo שהליבה שלו היא "האמת". מקבצי הדיסק שלו נבנה ה-ZIP שאתרי הצי מורידים.
- אתרי הלקוחות: כל אתר מחזיק עותק משלו של הליבה ב-
system/core/, ומחליף אותו בעצמו דרך פאנל עדכון ליבה.
ההעלאה ל-master נעשית עם פרטי FTP שמחזיקים רק אנשי Wizzo ומערכת הפריסה האוטומטית של Wizzo. מפתח חיצוני לא פורס ל-master: הוא מפתח מול אתר מקומי משלו ושולח Pull Request. מי שממזג, מפרסם ומקדם גרסה לצי הוא צוות Wizzo.
אתר פיתוח מקומי#
אין היום סביבת פיתוח "בלחיצה אחת": אין docker-compose, אין קובץ CONFIG_USER לדוגמה בריפו ואין קובץ סכימה (ראו מפת דרכים). אתר מקומי נבנה מחלקים, והדרך הבאה עובדת.
דרישות#
| רכיב | דרישה |
|---|---|
| PHP | 8.3 (composer.json של הליבה נועל platform.php = 8.3) |
| הרחבות | pdo_mysql, curl, mbstring, zip, json, openssl, gd |
| מסד נתונים | MySQL או MariaDB |
| שרת | Apache עם mod_rewrite ו-.htaccess שמנתב כל בקשה ל-index.php |
| Composer | להרצה ידנית בתוך system/core/ |
פירוט הדרישות ב-דרישות מערכת.
השלבים#
- שכפול הריפו לצד תיקיית האתר:
git clone https://github.com/wizzo-products/wizzo50_core.git
- שלד אתר: תיקיית אתר רגילה עם
index.php,application/ו-themes/. מבנה התיקיות ב-מבנה התיקיות של אתר, והקמה מלאה ב-התקנת אתר חדש. - הליבה כ-symlink: במקום להעתיק את
api/coreלאתר, מקשרים אותו. כל עריכה בריפו נראית באתר מיד.
mkdir -p mysite/system
ln -s "$PWD/wizzo50_core/api/core" mysite/system/core
ln -s "$PWD/wizzo50_core/api/js" mysite/system/js
- תלויות Composer: הליבה דורשת
system/core/vendor/autoload.phpבזמן ריצה (למשלPAGE::is_mobile()טוען אותו). ה-vendor/לא בריפו ואיןcomposer.lock, ולכן מריצים ידנית:
cd wizzo50_core/api/core
composer install --no-dev
vendor/ נוצר בתוך api/core/ של העותק שלכם, ולכן הוא יופיע כקבצים לא ממוענים. אל תוסיפו אותו ל-commit. פרטים ב-חבילות Composer.index.phpשל האתר מגדיר אתCONFIG_USERואז טוען את הליבה. רשימת המפתחות המלאה ב-CONFIG_USER וב-קונפיגורציה:
<?php
class CONFIG_USER
{
static $core_path = __DIR__ . "/system/core";
static $cache_folder = "cache";
static $models_folder = "application/models";
static $db_type = "PDO";
static $db_host = "127.0.0.1";
static $db_port = 3306;
static $db_dbname = "wizzo_local";
static $db_user = "wizzo";
static $db_password = "local-password";
static $db_prefix = "CRM";
static $admin_url = "wizzocms";
static $default_module = "home";
static $allow_cache = false;
}
require __DIR__ . "/system/core/core.php";
שמות המפתחות מאומתים מול api/core/collections/CONFIG.php ושאר הליבה. אין קובץ דוגמה רשמי, ולכן מפתח שחסר ב-CONFIG_USER מפיל את הבקשה עם Access to undeclared static property. אם נתקלתם בזה, הוסיפו את המפתח עם ערך ריק.
- טבלאות בסיס: ה-boot קורא
SELECT * FROM CRM_platformsבכל בקשה, ולכן הטבלה חייבת להיות קיימת עם שורה אחת לפחות. שאר הטבלאות הנדרשות ב-boot מפורטות ב-SQL להקמה וב-סכמת הטבלאות.
מלכודות של סביבה מקומית#
| מלכודת | למה זה קורה |
|---|---|
| ה-login לא נשמר | COOKIES::set() שולח תמיד secure=true ו-domain של . + שם המארח. על http:// או על מארח בלי נקודה (localhost) הדפדפן עלול לא לשמור את העוגייה. עדיף HTTPS מקומי ושם מארח כמו mysite.test. |
| דומיין לא מזוהה | CONFIG::init() בוחר שורה ב-CRM_platforms לפי $_SERVER['SERVER_NAME']. שם שלא נמצא נופל בשקט לשורה הראשונה בטבלה. |
| נתיבים שבורים בהרצה לא רגילה | CONFIG::$base_path נגזר מהסקריפט הראשי של הבקשה (debug_backtrace()). php -S עם router script או include מסקריפט אחר ישנה את כל הנתיבים. |
| תאריכים בשעון ישראל | CONFIG::preinit() קובע Asia/Jerusalem בלי קשר להגדרות ה-PHP שלכם. |
| קריאות החוצה | חלק מהכלים פונים לשירותי Wizzo Market. על אתר מקומי הם יחזרו שגיאה, וזה צפוי. |
משימות cron מקומית#
משימות הרקע רצות מ-CLI עם שורה אחת ב-crontab. MISC::cli_check() הופך כל key=value מה-argv ל-$_GET, ואת url= ל-REQUEST_URI:
* * * * * /usr/bin/php /path/to/mysite/index.php url=system/cron_runner tk=<cron_runner_token>
הטוקן נשמר ב-CRM_params תחת cron_runner_token. פרטים ב-מנהל משימות.
מ-api/core לאתר חי#
שינוי קובץ וצפייה בו#
כשהליבה מקושרת ב-symlink, שמירת קובץ ב-api/core/ משנה את האתר המקומי מיד. אם allow_cache דלוק, או שהשינוי נוגע ב-SCSS, ב-JS מקובץ או בטבלה שנשמרת במטמון, צריך לנקות מטמון: ראו ניקוי ותחזוקה. מטמון הפלטפורמות והפרמטרים נשמר ל-30 יום, ולכן שינוי ב-CRM_platforms או ב-CRM_params לא נראה עד לניקוי.
סקריפטי הפריסה (publish_scripts)#
התיקייה publish_scripts/ בריפו מכילה סקריפטי Node להעלאת קבצים לשרת. אלה הרלוונטיים לליבה:
| פקודה (מריצים משורש הריפו) | מה עושה |
|---|---|
npm run watch:api | צופה בתיקיית api/ (chokidar) ומעלה או מוחק ב-FTP כל קובץ שהשתנה. מצב העבודה היומיומי של צוות Wizzo. |
npm run publish:api | מעלה את api/ ל-API_FTP_PATH: מלא, או רק קבצים שהשתנו כש-WIZZOAGENT_CHANGED_FILES מוגדר. |
npm run publish:dir <dir> [dev|prod] | אותו סקריפט לכל תיקייה. קידומת משתני הסביבה נגזרת משם התיקייה (api נותן API_FTP_*). |
npm run wizzoagent_deploy | הפריסה האוטומטית אחרי merge: מריצה npm run publish:api production. |
npm run build:site, npm run publish:site | בנייה והעלאה של אתר התיעוד (תיקיית website/), לא של הליבה. |
משתני הסביבה נקראים מקובץ .env בשורש הריפו (או .env.development ו-.env.production). לכל תיקייה יעד חמישה משתנים:
API_FTP_HOST=ftp.example.com
API_FTP_USER=deploy-user
API_FTP_PASSWORD=...
API_FTP_PATH=/site/system/
API_FTP_SCHEME=sftp
API_FTP_PORT אופציונלי (ברירת מחדל 21, או 22 ב-sftp). API_FTP_PATH מצביע על תיקיית system/ של האתר היעד: api/core נוחת ב-system/core ו-api/js ב-system/js.
כשמכוונים אותו ל-master, כל Ctrl+S בעורך משנה קובץ בליבה שאתרי הצי מורידים בעדכון הבא. אין staging ואין rollback ל-master. לפני הרצה ודאו ש-.env מצביע לסביבת פיתוח, ולא תשמרו קבצים ששבורים תחבירית.
publish.generic.js מזהה את הפרמטר השני רק אם הוא בדיוק dev או prod. production (כפי ש-wizzoagent_deploy.js מעביר) מתעלם בשקט. כשקיימים גם .env.development וגם .env.production, הסקריפט מעלה לשניהם ברצף.עוד שלושה דברים שחשוב לדעת על ההעלאה:
- לא נמחק כלום בשרת. העלאה מלאה או חלקית לא מוחקת קובץ שהוסר מהריפו, כך שקבצים ישנים נשארים בשרת ובכל ZIP שנבנה ממנו. מחיקה ידנית נדרשת (או
watch:api, שכן מוחק). - FTP רגיל אינו מוצפן. ברירת המחדל היא
ftpעםsecure: false. העדיפוAPI_FTP_SCHEME=sftp. - סקריפטי המובייל (
build.ps1,build_publish.ps1,build-publish-ios.sh,publish-android.js) וסקריפטיvue-cli-serviceב-package.jsonשייכים לאפליקציה שאינה בריפו. אין להם שימוש בעבודה על הליבה.
מה קורה ב-master אחרי ההעלאה#
אין hook ואין build. הקבצים פשוט יושבים ב-system/core של ה-master. כשאתר כלשהו שואל מה הגרסה העדכנית (check_version/get), ה-master מחשב טביעת אצבע (md5 של נתיב, גודל וזמן עדכון של כל קובץ בליבה, בלי check_version.php). אם אין ZIP שמתאים לטביעה, הוא בונה backups/core-<version>-<fingerprint>.zip ומגיש אותו.
מכאן שני דברים:
- כל שינוי בקובץ בליבת ה-master יוצר ZIP חדש, גם בלי לשנות את
version.txt. אתר יוריד אותו רק אם מספר הגרסה עלה (ראו גרסאות). - ה-ZIP נבנה מהדיסק החי. קובץ debug או קובץ זמני ששכחתם בתיקיית הליבה של ה-master יגיע לכל האתרים.
controllers/check_version.php עצמו לא נארז ב-ZIP בכוונה: שינוי בו מגיע לאתרים רק בהעלאה ידנית, כדי ש-master פגום לא יוכל לשבש את כל הצי.
עדכון גרסה באתר#
בפאנל הניהול של כל אתר יש מסך "עדכון גרסה" ({admin}/wizzo_update). הפעולה get מבצעת את הרצף הבא (ממומש ב-admin/wizzo_update.php):
- בדיקות מקדימות (
preflight): גרסת PHP מספקת (php_floorמה-master), הרחבתzip, מקום פנוי בדיסק (לפחות 64MB או פי ארבעה מגודל ה-ZIP) וחיבור למסד הנתונים. כשל מפסיק את העדכון לפני שנגע בכל קובץ. - הורדה ואימות: ה-ZIP יורד לשורש האתר ומאומת מול sha256 שה-master מצהיר עליו.
- פריסה בצד: החילוץ נעשה ל-
system/core_new_<timestamp>, ונבדק שיש בוcore.phpו-version.txt. - החלפה: שני
renameברצף. הליבה הישנה הופכת ל-system/core_bup_<timestamp>והחדשה נכנסת במקומה. - בדיקה אחרי החלפה (
postflight): הבקשה/system/core_pingלאתר עצמו. אם היא מחזירה 5xx, תשובה לא תקינה,db:falseאו גרסה שונה מהצפויה, הליבה החדשה מועברת ל-core_failed_<timestamp>והישנה חוזרת. - סנכרון שאר החלקים (תמיד, גם כשהליבה כבר עדכנית): מבנה הטבלאות (
update_db), הפאנלים (update_panel), משימות המערכת של ה-cron (update_cron_system) וקבציsystem/js(update_js), והעלאתattaches_versionכדי לרענן נכסים.
האתר שומר חמש גרסאות גיבוי אחרונות (core_bup_*). ההיסטוריה נרשמת בטבלה CRM_wizzo_update_log.
אם האתר לא מצליח לפנות לעצמו בבקשת HTTP (למשל שרת בלי hairpin NAT), postflight מחזיר הצלחה, ולכן החזרה האוטומטית לא תופעל. בדקו את core_ping ידנית אחרי עדכון על סביבה כזו.
התהליך המלא, כולל ערוצי latest ו-stable, בדף עדכון ליבה.
בדיקה שהליבה חיה#
/system/core_ping מחזיר JSON קטן בלי מטמון, ושימושי גם לבדיקת עשן בסביבה שלכם:
{"ok": true, "version": "5.0.115", "db": true, "php": "8.3.0"}
db: false אומר שהליבה עלתה אבל מסד הנתונים לא ענה לשאילתה SELECT 1. לדיבוג ניתוב של כתובת בודדת מוסיפים ?__router_trace=1 (ראו דיבוג ניתוב), ולדיבוג שאילתות דיבוג SQL.
ראו גם#
- מבנה הריפו: מה יושב בכל תיקייה.
- תרומת קוד ו-PR: מענף ועד מיזוג.
- בדיקות: איך בודקים שינוי בליבה מול אתר.
- עדכון ליבה ו-גרסאות: המנגנון המלא והמספור.
- מפת דרכים לתקן: סביבת פיתוח אחידה, CI וחתימת גרסאות.