הקונפיגורציה של אתר היא מחלקה אחת, CONFIG_USER, בקובץ system/config.php של האתר. הליבה לא מגדירה אותה: היא מצפה שהאתר כבר הגדיר אותה לפני שהיא נטענת, ומרחיבה אותה במחלקה משלה. הדף הזה מפרט כל מאפיין שהליבה קוראת, אילו חובה, מה קורה כשהם חסרים, ואיפה בקוד כל אחד נקרא.
נתיבי קבצי ליבה בדף כתובים יחסית ל-api/core בריפו (למשל collections/DB.php). בעת הפריסה התיקייה הזו יושבת ב-system/core/ של האתר, ראו מבנה התיקיות של אתר. רשימת הפניות בסגנון ספר חתימות נמצאת ב-CONFIG_USER (רפרנס).
איפה הקונפיגורציה מוגדרת ומתי היא נטענת#
הסדר הוא קבוע, והוא נובע מ-index.php של האתר ומ-core.php:
index.phpעושהrequire_once("system/config.php"). הקובץ מגדירclass CONFIG_USERעם מאפיינים סטטיים.index.phpהופך אתCONFIG_USER::$core_pathמנתיב יחסי לנתיב מוחלט (ראו הערה בהמשך).index.phpטוען אתcore.phpשל הליבה. הוא טוען את כל קבציcollections/*.php, ביניהםcollections/CONFIG.phpשמגדירclass CONFIG extends CONFIG_USER.CONFIG::preinit()רץ ראשון, אחריוMISC::cli_check()ואזCONFIG::init(). רק אחרי כל אלה נטעןapplication/includes/init.phpשל האתר, ואחריו בדיקת ה-page cache וניתוב הבקשה.
כל הקוד של הליבה והאתר פונה אל CONFIG::$something (לא אל CONFIG_USER). בזכות הירושה שני השמות מצביעים על אותם נתונים, אבל CONFIG היא גם זו שמוסיפה את המאפיינים שהיא מחשבת בעצמה.
<?php
// system/config.php: הקובץ היחיד שהאתר כותב, הליבה לא נוגעת בו
class CONFIG_USER
{
static $db_type = "PDO";
// ... ראו את הטבלה ואת הדוגמה המלאה בהמשך
}
CONFIG היא מחלקה רגילה עם מאפיינים סטטיים. קריאה ישירה למאפיין שאף מחלקה לא הצהירה עליו (CONFIG::$mail_queue באתר שלא הגדיר אותו) זורקת Error: Access to undeclared static property, והעמוד נופל. הליבה קוראת בצורה מוגנת (isset, property_exists) רק את המאפיינים שבקבוצה "אופציונליים" בטבלה. כל השאר חייבים להיות מוצהרים, גם אם הערך שלהם ריק או false.בקוד האתר כותבים static $x = ... (בלי public), וזה ציבורי כברירת מחדל ב-PHP. אותו סגנון משמש בכל הליבה.
core_path: מה index.php עושה איתו#
ב-system/config.php רושמים את core_path כנתיב יחסי, "system/core" בהתקנה רגילה. index.php של האתר ממיר אותו לנתיב מוחלט, והליבה קוראת אותו כנתיב מוחלט בכל מקום (CONFIG::$core_path מופיע בקוד הליבה כ-470 פעמים).
<?php
// index.php של האתר (ללא display_errors: בייצור לא מציגים שגיאות בדפדפן)
error_reporting(E_ALL);
ob_start("ob_gzhandler");
require_once("system/config.php");
// מציאת נתיב הליבה האמיתי
$ex = explode("../", CONFIG_USER::$core_path);
$realPath = dirname(__FILE__);
if (CONFIG_USER::$core_path != "system/core") for ($i = 0; $i < (count($ex)); $i++) $realPath = dirname($realPath);
CONFIG_USER::$core_path = $realPath . "/" . $ex[(count($ex) - 1)];
// טעינת הליבה
require_once(CONFIG_USER::$core_path . "/core.php");
עבור "system/core" המשתנה $realPath נשאר שורש האתר והתוצאה היא <שורש האתר>/system/core. אם הליבה יושבת מחוץ לאתר (ליבה משותפת למספר אתרים), הערך נכתב עם קידומת ../, והלולאה מטפסת count($ex) רמות מעל שורש האתר, כלומר רמה אחת יותר ממספר ה-../ שכתבתם.
אם כותבים core_path מוחלט (למשל __DIR__ . "/system/core"), התנאי != "system/core" מתקיים, הלולאה מטפסת רמה אחת מעל השורש והנתיב המתקבל שגוי. השתמשו ב-"system/core" או בנתיב יחסי עם ../, ובדקו את התוצאה כשמעבירים ליבה לתיקייה משותפת.
admin/wizzo_update.php מחשב dirname(CONFIG::$core_path) ומניח שהיא התיקייה שמכילה את הליבה: הוא פורס את הגרסה החדשה ל-core_new_<תאריך> ומשאיר גיבוי core_bup_<תאריך> באותה תיקייה (שורות 506 ו-531). הליבה חייבת לשבת בתיקייה שבה מותר ליצור תיקיות אחיות. ראו עדכון ליבה.מאפיינים ש-CONFIG מגדירה בעצמה#
אל תצהירו על המאפיינים האלה ב-CONFIG_USER. collections/CONFIG.php מצהיר עליהם (שורות 6-16, מסומנים שם "Do not defind this variables") ומחשב אותם בכל בקשה.
| מאפיין | מי קובע אותו | משמעות |
|---|---|---|
$protocol | preinit, שורות 25-32 | "https" ב-CLI, אחרת לפי $_SERVER["HTTPS"] == "on" |
$base_path | preinit, שורות 35-37 | התיקייה של סקריפט הכניסה (index.php), כלומר שורש האתר. נלקח מה-backtrace, לא מ-getcwd() |
$db_fullprefix | init, שורות 66-67 | $db_prefix . "_" (כלומר CRM_). משמש לשאילתות SQL גולמיות (כ-190 מקומות) |
$platform_data | init, שורות 81-106 | שורת הפלטפורמה הנוכחית מ-CRM_platforms, ראו להלן |
$env_url | init, שורות 79, 98, 121 | כתובת הבסיס של הסביבה: ה-host המבוקש כשמדובר ב-allowed domain, אחרת $site_url |
$site_url | init, שורה 111 | <protocol>://<platform domain>/ (עם סלאש סוגר) |
$original_site_url | init, שורה 112 | אותו דבר לפי $_SERVER['HTTP_HOST'] המקורי |
$base_domain | init, שורות 114-118 | $set_base_domain אם הוגדר, אחרת $_SERVER['HTTP_HOST']. משמש לדומיין של cookies |
$lang | init, שורה 129 | ה-id של הפלטפורמה שנבחרה (גם MISC::$GLOBALS["lang"]) |
$system_type | ROUTER, collections/ROUTER.php שורות 176 ו-413 ואילך | "client" או "admin", נקבע לפי ה-URL |
$site_config | לא מוקצה בשום מקום בליבה | מוצהר בלבד, אין לו שימוש |
CONFIG::preinit#
preinit() רץ לפני כל גישה למסד הנתונים ועושה ארבעה דברים:
- קובע
date_default_timezone_set('Asia/Jerusalem'). האזור קבוע בקוד ולא ניתן להגדרה ב-CONFIG_USER. - קובע את
$protocolואת$base_path. - הופך את
$models_folderל-נתיב מוחלט:$base_path . "/" . $models_folder, ואם הוא מכיל../עובר דרךrealpath(). - עושה את אותו דבר ל-
$cache_folder.
כש-$cache_folder או $models_folder מכילים ../, preinit מפעיל realpath(). אם התיקייה לא קיימת, realpath() מחזיר false והנתיב נשבר בשקט. כשמשתמשים ב-"../cache" צרו את התיקייה לפני העלאת האתר.
CONFIG::init: בחירת הפלטפורמה#
init() קורא את CRM_platforms דרך cache_engine::get("platforms", ..., 24*30, false) (מטמון גלובלי ל-30 יום, מפתח לפי עמודת domain) וממפה את הבקשה לפלטפורמה:
- התאמה מדויקת של
$_SERVER['SERVER_NAME']לעמודתdomain. - אם אין, מחפשים בעמודת
allowed_domainsשל כל פלטפורמה (מפוצלת לפיMISC::bgl_explode) שם שמכיל את ה-host. אם נמצא, גם$env_urlמתעדכן ל-host המבוקש. - אם עדיין אין, נבחרת הפלטפורמה הראשונה בטבלה.
כלומר הליבה אף פעם לא נכשלת בבחירת פלטפורמה. הדחייה של דומיין לא מוכר קורה אחר כך, ב-PAGE::load (ראו $ignore_domain_check). פרטי הפלטפורמות בדף פלטפורמות ורב-לשוניות.
הטבלה המלאה: מאפיינים שהאתר חייב להצהיר עליהם#
ה"חובה" בטבלה פירושו שהליבה קוראת את המאפיין בלי isset. גם מאפיין שנקרא רק בתנאי (למשל SMTP) מסומן, עם התנאי בעמודת המשמעות, כי כשהתנאי מתקיים המאפיין חייב להיות קיים.
מסד נתונים#
| מאפיין | סוג | חובה | דוגמה | משמעות | נקרא ב- |
|---|---|---|---|---|---|
$db_type | string | כן | "PDO" | סוג החיבור: "PDO" (MySQL, מומלץ), "mysql" (הרחבה ישנה שהוסרה מ-PHP 7), "pg" (PostgreSQL), "clickhouse" | collections/DB.php:78 |
$db_host | string | כן | "localhost" | שרת המסד | DB.php:83 |
$db_dbname | string | כן | "mysite" | שם בסיס הנתונים. נקרא גם בשאילתות INFORMATION_SCHEMA של פאנלי הניהול | DB.php:83 |
$db_user | string | כן | "mysite" | משתמש | DB.php:83 |
$db_password | string | כן | "secret" | סיסמה | DB.php:83 |
$db_port | int | לא (isset) | 3306 | פורט. ב-PDO מצורף ל-DSN רק אם הוגדר; ב-ClickHouse ברירת המחדל 8123; ב-pg הפורט קבוע 5432 בקוד | DB.php:83, DB.php:124 |
$db_protocol | string | לא (isset) | "https" | ClickHouse בלבד: ברירת מחדל "http" | DB.php:125 |
$db_prefix | string | כן | "CRM" | קידומת הטבלאות בלי קו תחתון | CONFIG.php:67 |
נתיבים וניתוב#
| מאפיין | סוג | חובה | דוגמה | משמעות | נקרא ב- |
|---|---|---|---|---|---|
$core_path | string | כן | "system/core" | נתיב הליבה (יחסי בקובץ, מוחלט אחרי index.php). בלי / בסוף | core.php:24, 470 מקומות |
$models_folder | string | כן | "application/models" | תיקיית ה-models, יחסית לשורש האתר. הופך למוחלט ב-preinit | CONFIG.php:40, MODULE.php:226 |
$cache_folder | string | כן | "cache" | תיקיית המטמון, יחסית לשורש האתר (או "../cache"). הופך למוחלט ב-preinit | CONFIG.php:52, cache_engine.php:101 |
$admin_url | string | כן | "wizzocms" | ה-slug של פאנל הניהול, בלי סלאשים. מוזרק ישירות לתוך ביטוי רגולרי | ROUTER.php:411-441 |
$default_module | string | כן | "home" | הקונטרולר של דף הבית (כשה-URL ריק) | ROUTER.php:178 |
ROUTER בונה '/^' . CONFIG::$admin_url . '$/' בלי preg_quote. השתמשו באותיות, ספרות ומקף בלבד. תו מיוחד של regex (נקודה, סוגריים) משנה את התאמת הכתובת. בנוסף, ה-slug הוא נתיב הפאנל הציבורי, ולכן ערך שאפשר לנחש מקל על תקיפה: ראו הקשחה.קבצי ה-.chc של cache_engine, ה-page cache, וה-composer ו-perf_advisor נשמרים תחת $cache_folder. לעומת זאת מטמוני ה-SCSS, ה-minify וה-Smarty כתובים בקוד כנתיב יחסי cache/... (collections/FILES.php:10, FILES.php:435, controllers/minify.php:90) ומתעלמים מהמאפיין. אם מעבירים את $cache_folder למקום אחר, התיקייה cache/ בשורש האתר עדיין חייבת להתקיים וניתנת לכתיבה. פירוט ב-איך המטמון עובד.
התנהגות#
| מאפיין | סוג | חובה | דוגמה | משמעות | נקרא ב- |
|---|---|---|---|---|---|
$allow_cache | bool | כן | true | מאפשר שמירה והגשה של page cache (רק בצד לקוח) ופעולות cache_engine. כש-false, cache_engine לא שומר דבר | core.php:43, cache_engine.php:120, :448 |
$use_smarty | true / "plain" / אחר | כן | true | מצב התבניות: true = Smarty; "plain" = החזרת הקובץ כמות שהוא; כל ערך אחר = ענף ישן שמריץ את התבנית עם eval. אפשר לדרוס בכל קריאה דרך הגדרות התבנית | collections/FILES.php:205-256 |
$minify_html | bool | כן | true | false מבטל כיווץ HTML של העמוד | collections/PAGE.php:663 |
$ignore_domain_check | bool | כן | false | true מדלג על die("URL ERROR") כשה-host לא מופיע ב-domain או ב-allowed_domains של הפלטפורמה. נקבע ל-true אוטומטית בהרצת CLI | PAGE.php:719, MISC.php:167 |
בדיקת הדומיין חלה על בקשות צד-לקוח בלבד, ופטורות ממנה בקשות ל-minify ול-Tools ול-CRM.js. בקשה לדומיין שלא רשום בפלטפורמות מקבלת את הפלטפורמה הראשונה ואז נעצרת ב-URL ERROR. כדי להגיש את האתר מכתובת נוספת רשמו אותה ב-allowed_domains במקום להדליק $ignore_domain_check.
אחסון קבצים#
| מאפיין | סוג | חובה | דוגמה | משמעות | נקרא ב- |
|---|---|---|---|---|---|
$storage_remote | string | כן | "" | "" = דיסק מקומי (media/Storage), "ftp", "s3" (טוען את ספריית AWS בכל בקשה) | core.php:28, STORAGE.php:195 |
$storage_remote_url | string | כש-ftp | "https://cdn.example.com" | קידומת ה-URL של קבצים שהועלו ב-FTP | STORAGE.php:704 |
$storage_remote_ftp_host | string | כש-ftp | "ftp.example.com" | שרת FTP | STORAGE.php:740 |
$storage_remote_ftp_username | string | כש-ftp | "cdnuser" | משתמש FTP | STORAGE.php:768 |
$storage_remote_ftp_password | string | כש-ftp | "secret" | סיסמת FTP | STORAGE.php:768 |
מפתחות S3 לא ב-CONFIG. הליבה קוראת אותם מ-MISC::$GLOBALS["Storage_remote_s3_key"], ["Storage_remote_s3_secret"] ו-["Storage_remote_s3_bucket"] (STORAGE.php:446-452), ואף קובץ בליבה לא מגדיר אותם. האתר מציב אותם ב-application/includes/init.php (ראו הדוגמה בהמשך). פרטי ההעלאה ב-STORAGE: העלאה ואחסון.
כתובת קובץ ב-S3 נבנית כ-https://s3.amazonaws.com/<path> (STORAGE.php:705): שם ה-bucket לא מתווסף אליה על ידי הקוד, ולכן צריך שיהיה חלק מה-path אם ה-URL צריך אותו. בנוסף, בענף ההעלאה של STORAGE הענף s3 לא מסתיים ב-break, ולכן אחרי ההעלאה ל-S3 מתבצעת גם עותק מקומי אל media/Storage (STORAGE.php סביב שורות 442-470). אל תניחו שבשימוש ב-S3 תיקיית media/ נשארת ריקה.
דואר#
| מאפיין | סוג | חובה | דוגמה | משמעות | נקרא ב- |
|---|---|---|---|---|---|
$mail_queue | bool | כן, בשליחה דרך mail_tpl | false | true = ההודעה נכנסת לתור ונשלחת מאוחר יותר; false = שליחה מיידית (והתוצאה נרשמת בתור) | libraries/mail_tpl.php:254 |
$mail_is_smtp | bool | כן, בכל שליחה | true | רק === true מפעיל SMTP. אחרת PHPMailer שולח דרך mail() של PHP | mail_tpl.php:149, MISC.php:789 |
$mail_smtp_host | string | כש-SMTP | "smtp.example.com" | שרת | MISC.php:792 |
$mail_smtp_port | int | כש-SMTP | 587 | פורט | MISC.php:797 |
$mail_smtp_secure | string | כש-SMTP | "tls" | "tls" או "ssl" | MISC.php:796 |
$mail_smtp_auth | bool | כש-SMTP | true | הזדהות | MISC.php:793 |
$mail_smtp_username | string | כש-SMTP | "user" | משתמש | MISC.php:794 |
$mail_smtp_password | string | כש-SMTP | "secret" | סיסמה | MISC.php:795 |
פירוט נוסף בדף שליחת דואר.
מאפיינים אופציונליים#
הליבה קוראת אותם רק אחרי isset או property_exists, ולכן אפשר להשמיט אותם:
| מאפיין | סוג | ברירת מחדל כשחסר | משמעות | נקרא ב- |
|---|---|---|---|---|
$set_base_domain | string | $_SERVER['HTTP_HOST'] | דומיין בסיס ל-cookies, למשל ".example.com" כדי לשתף cookie בין תת-דומיינים | CONFIG.php:114 |
$environment | string | ללא סינון | "dev" או "production": סינון סקריפטים של tag manager לפי עמודת environment (הערך "all" תמיד עובר) | controllers/minify.php:321-323 |
$show_wizzo_credits | bool | true | false מסיר את <meta name="copyright"> של WIZZO מראש העמוד | PAGE.php:521 |
$admin_countries | array או false | ללא הגבלה | קודי מדינה מותרים להתחברות לפאנל. הקובץ system/admin_countries.json קודם למאפיין הזה | libraries/admin_countries.php:40 |
$mask | false / true / array | כבוי | מצב הסוואה: מפה של נתיבים אמיתיים לנתיבים נייטרליים. true = ברירת מחדל מובנית. ראו מצב הסוואה (MASK) | collections/MASK.php:60 |
$mask_words | array | ריק | החלפות מילים לפלט בלבד (אמיתי => נייטרלי), פעיל רק כש-$mask פעיל | MASK.php:96 |
isset מחזיר false גם למאפיין שהוצהר עם null. כדי לכבות אופציה כתבו false או מחרוזת ריקה במקום null.מאפיין אחד שרידי: $zend_db נקרא רק ב-zend_query של DB.php (שורה 1282), פונקציה שבורה שלא נקראת מהליבה. אל תצהירו עליו.
שכבות קונפיגורציה אחרות#
CONFIG_USER מכילה רק את מה שחייב להיות ידוע לפני שיש חיבור למסד: חיבור, נתיבים ומצבי הפעלה. כל השאר חי במסד, ומנוהל מפאנל הניהול:
- פלטפורמה (
CRM_platforms): דומיין,allowed_domains, ערכת נושא ברירת מחדל (deftheme), כותרת ותיאור SEO ברירת מחדל, כיוון שפה. השורה הנבחרת היאCONFIG::$platform_data. ראו פלטפורמות ורב-לשוניות. - פרמטרים (
CRM_params): מפתח וערך (sysName,value) שנטענים כולם בבקשה לזיכרון דרךPARAMS::init()ונקראים עםPARAMS::get("key"). מטמון של 30 יום. ראו פרמטרים ומילים. - מילים (
CRM_langs_words): טקסטים לפי שפה, דרךLANGS::init_words(), מטמוןwords_lang<lang>ל-4 שעות.
כלל אצבע: ערך שמשתנה בין סביבות (dev ו-production) או מכיל סוד נשאר ב-CONFIG_USER; ערך שעורך תוכן או מנהל אמור לשנות נכנס ל-PARAMS.
דוגמה מינימלית#
האתר הקטן ביותר שרץ: מסד MySQL, אחסון מקומי, בלי SMTP.
<?php
// system/config.php
class CONFIG_USER
{
// מסד נתונים
static $db_type = "PDO";
static $db_host = "localhost";
static $db_dbname = "mysite";
static $db_user = "mysite";
static $db_password = "change-me";
static $db_prefix = "CRM"; // חייב להישאר CRM
// נתיבים וניתוב
static $core_path = "system/core"; // יחסי: index.php הופך אותו למוחלט
static $models_folder = "application/models";
static $cache_folder = "cache";
static $admin_url = "wizzocms";
static $default_module = "home";
// התנהגות
static $allow_cache = true;
static $use_smarty = true;
static $minify_html = true;
static $ignore_domain_check = false;
// אחסון מקומי
static $storage_remote = "";
// דואר: PHP mail()
static $mail_queue = false;
static $mail_is_smtp = false;
}
דוגמה לייצור: S3, SMTP ואופציות#
אתר ייצור עם הסביבה מוגדרת, SMTP, הסוואה, והגבלת מדינות. כל הערכים שבדוגמה הם מקומות שמורים, ולא ערכים אמיתיים.
<?php
// system/config.php (מוגן ע"י system/.htaccess ואסור לשמור אותו ב-git)
class CONFIG_USER
{
static $db_type = "PDO";
static $db_host = "127.0.0.1";
static $db_port = 3306;
static $db_dbname = "prod_site";
static $db_user = "prod_site";
static $db_password = "from-your-secret-store";
static $db_prefix = "CRM";
static $core_path = "system/core";
static $models_folder = "application/models";
static $cache_folder = "cache";
static $admin_url = "manage-7f3a"; // slug לא צפוי, אותיות ומקף בלבד
static $default_module = "home";
static $allow_cache = true;
static $use_smarty = true;
static $minify_html = true;
static $ignore_domain_check = false;
static $environment = "production";
static $show_wizzo_credits = false;
static $set_base_domain = ".example.com"; // cookie משותף לכל תתי-הדומיינים
static $admin_countries = ["IL"];
static $mask = true; // הסוואת נתיבי theme / minify / system/js
// אחסון ב-S3: המפתחות ב-MISC::$GLOBALS (ראו init.php בהמשך)
static $storage_remote = "s3";
// דואר דרך SMTP
static $mail_queue = true;
static $mail_is_smtp = true;
static $mail_smtp_host = "smtp.example.com";
static $mail_smtp_port = 587;
static $mail_smtp_secure = "tls";
static $mail_smtp_auth = true;
static $mail_smtp_username = "mailer@example.com";
static $mail_smtp_password = "from-your-secret-store";
}
<?php
// application/includes/init.php: נטען בכל בקשה אחרי CONFIG::init()
MISC::$GLOBALS["Storage_remote_s3_key"] = "AKIA..."; // להביא ממשתנה סביבה או מכספת
MISC::$GLOBALS["Storage_remote_s3_secret"] = "...";
MISC::$GLOBALS["Storage_remote_s3_bucket"] = "my-bucket";
system/config.php מכיל סיסמת מסד נתונים וסיסמת SMTP. הוא מוגן מהגשה ב-HTTP על ידי system/.htaccess (שהליבה כותבת), אבל אסור להעלות אותו ל-git ואסור שיהיה קריא בשרתים שלא מריצים Apache. אם אפשר, קראו את הערכים ממשתני סביבה. ראו מודל האבטחה.כשמשהו לא מתנהג כמצופה, בדקו קודם את CONFIG::$platform_data (איזו פלטפורמה נבחרה) ואת CONFIG::$system_type (אדמין או לקוח), אלה שני הערכים שמשנים את רוב ההחלטות של הליבה.