סקירת ארכיטקטורה

מפה של WIZZO CMS מלמעלה: ליבה מול אתר, שכבות הקוד, מודל הנתונים, שכבות המטמון, נקודות ההרחבה ותכונות התכנון שכדאי להכיר לפני שנוגעים בקוד.

⏱ 8 דק' קריאה 1375 מילים ערוך דף זה ב-GitHub

העמוד הזה הוא המפה. הוא לא מסביר כל פונקציה, אלא מראה מה יושב איפה ולאן ממשיכים לקרוא. מי שרוצה לעקוב אחרי בקשה אחת מהשרת ועד ה-HTML ימצא את זה ב-מחזור חיי בקשה.

הליבה יושבת ב-api/core/ בריפו ונפרסת ל-system/core/ באתר. כל הנתיבים בעמוד הם יחסית ל-api/core, ו-{admin} בכתובות הניהול הוא CONFIG::$admin_url.

ליבה ואתר: שני עולמות#

WIZZO CMS בנוי מחלוקה חדה אחת. הליבה היא קוד משותף שאף אתר לא עורך: אותה גרסה ממש (version.txt) רצה על כל אתרי הצי, ומתעדכנת בפעולה אחת (עדכון ליבה). האתר הוא כל מה שמיוחד ללקוח: הקונטרולרים, התבניות, ה-theme, ההגדרות והנתונים שלו.

הליבההאתר
מיקוםapi/core בריפו, system/core באתרשורש האתר: application/, themes/, system/config.php
מי עורךצוות הפיתוח של הפלטפורמה, דרך PRמפתח האתר
הגדרותCONFIG (מחלקה פנימית)CONFIG_USER ב-system/config.php (קונפיגורציה)
נתוניםסכמה ושורות יסוד (סכמת הטבלאות)תוכן, מודולים רשומים, כתובות

הקשר בין השניים הוא חד-כיווני: הליבה מחפשת קבצים באתר בנתיבים קבועים (application/controllers/<module>.php, application/includes/*.php, themes/<name>/index.php) וטוענת אותם, והאתר קורא לאובייקטים סטטיים של הליבה. מבנה התיקיות המלא ב-מבנה התיקיות של אתר.

לא עורכים את system/core באתר חי

שינוי בתוך system/core נמחק בעדכון הליבה הבא, ואם הוא נעשה על אתר אחד בלבד הוא יוצר סטייה שקשה לאתר. כל מה שאתר צריך להתאים נעשה דרך נקודות ההרחבה שלמטה.

השכבות#

 דפדפן / cron / MCP
        |
        v
 [1] כניסה:     .htaccess  ->  index.php  ->  core.php
        |
        v
 [2] Collections (מחלקות סטטיות, נטענות כולן בכל בקשה)
        CONFIG  DB  cache_engine  PAGE  ROUTER  MODULE  FILES  MISC
        SEO  PARAMS  LANGS  ADMIN  LOGIN  STORAGE  COOKIES  SESSION ...
        |
        v
 [3] ניתוב ומודולים:   ROUTER  ->  MODULE::get_html
        |                         |                  |
        |                         v                  v
        |        application/controllers   controllers/ (קונטרולרי מערכת)
        |                         |                  |
        v                         +--------+---------+
 [4] תצוגה:  $this->view()  ->  Smarty   ->   theme (TEMPLATE_<name>)
        |
        v
 [5] PAGE::output  ->  HTML  ->  מטמון עמוד  ->  הדפדפן

 לצד כל אלה:
   libraries/   ספריות שנטענות לפי דרישה ($this->load->library)
   admin/       פאנלי הניהול של הליבה (ADMINMODULE_<name>)
   addons/      ספריות צד שלישי: Smarty, PHPMailer, scssphp, JShrink...

1. כניסה ואתחול#

קובץ .htaccess של האתר מגיש ישירות קבצים סטטיים וקבצי JS ו-CSS שכבר נוצרו במטמון, ומעביר כל כתובת אחרת ל-index.php. הקובץ הזה קצר: הוא קורא את system/config.php, מחשב את הנתיב המוחלט של הליבה ומכניס את core.php. מ-core.php מתחיל כל החיים של הבקשה. הפירוט שורה אחר שורה ב-מחזור חיי בקשה.

2. Collections: שירותים סטטיים#

כל קובץ ב-collections/ מגדיר מחלקה עם מתודות סטטיות ונתונים סטטיים: DB, PAGE, ROUTER, MODULE, cache_engine, SEO, PARAMS ועוד. אין מופעים ואין הזרקת תלויות: מי שצריך מסד נתונים קורא DB::get_row(...), מי שצריך להגדיר כותרת קורא SEO::set(...). core.php טוען את כל הקבצים בתיקייה בלולאה אחת (glob), ולכן כולם זמינים מכל מקום בקוד. הקטלוג המלא ב-ה-Collections.

3. ניתוב ומודולים#

ROUTER::parse_friendly_url הופך את הכתובת למשתני $_GET (module, pname, id), ו-MODULE::get_html מוצא את הקובץ, יוצר את המחלקה וקורא למתודה. יש שני סוגי קונטרולרים:

  • קונטרולרי אתר: application/controllers/<name>.php, שחייבים שורה פעילה ב-CRM_modules. ראו קונטרולרים של אתר.
  • קונטרולרי מערכת: controllers/<name>.php בליבה, שעונים בכתובת /system/<name> ולא צריכים שורת מודול. הם משרתים את הממשקים הפנימיים: cron, minify, התחברות לניהול, MCP, בדיקות תקינות (קונטרולרי מערכת).

שני כלי הניתוב האחרים הם כתובות ידידותיות (CRM_seoUrl, עם ביטויים רגולריים) ו-הפניות 301 (CRM_redirections). כל הכללים ב-ניתוב.

4. תצוגה: Smarty ו-themes#

$this->view("x", [...]) טוען את application/views/x.tpl דרך Smarty (תבניות Smarty). התוצאה נכנסת למשתנה content של ה-theme: מחלקה TEMPLATE_<name> ב-themes/<name>/index.php יחד עם index.tpl, שמגדירה את מעטפת האתר, את ה-CSS וה-JS (ערכות נושא). הנכסים עצמם (SCSS, איחוד וכיווץ) מנוהלים על ידי PAGE ו-controllers/minify.php (צינור הנכסים, PAGE: נכסים, מטא ואירועים).

5. ספריות לפי דרישה#

הקוד הכבד אינו נטען בכל בקשה. תיקיית libraries/ מכילה ספריות כמו forms, panel_table, AdminModule, market_service שנטענות רק כשמישהו מבקש: $this->load->library("name") בקונטרולר, או אוטומטית בבקשות ניהול. מחלקות צד שלישי (Smarty, PHPMailer, scssphp, JShrink ועוד) יושבות ב-addons/; ה-Composer של הליבה והאתר ב-חבילות Composer.

6. מסגרת הניהול#

כתובת שמתחילה ב-/{admin}/... מנותבת למסגרת הניהול: לכל פאנל מחלקה ADMINMODULE_<name> בקובץ admin/<name>.php בליבה או ב-application/admin/<name>.php באתר, ואת הפאנלים הרשומים מגדירה הטבלה CRM_adminPanel_panels. המסגרת מספקת טבלאות (panel_table), טפסים (Form) והרשאות (סקירת פאנל הניהול, בניית פאנל).

מודל הנתונים במבט אחד#

כל טבלאות המערכת מתחילות ב-CRM_ (במסד של אתר טיפוסי יש עשרות כאלה). הקבוצות שחשוב להכיר:

קבוצהטבלאות לדוגמהתפקיד
פלטפורמות ושפותCRM_platformsאתר = פלטפורמה אחת או יותר, כל אחת עם domain, deftheme, direction; מזהה הפלטפורמה הוא גם מזהה השפה (CONFIG::$lang). ראו פלטפורמות ורב-לשוניות
ניתובCRM_modules, CRM_seoUrl, CRM_redirectionsאילו קונטרולרים פעילים, כתובות ידידותיות והפניות
הגדרות ותרגוםCRM_params, CRM_langs_words, CRM_langs_words_contentפרמטרים גלובליים ומילות הממשק לפי שפה (פרמטרים ומילים)
ניהולCRM_adminPanel_*פאנלים, אפשרויות, מנהלים, קבוצות והרשאות
נכסיםCRM_minify_files, CRM_minify_groups, CRM_scriptsקבצי JS ו-CSS מאוחדים וסקריפטים של האתר
תוכןטבלאות האתר עצמו, ולרוב זוג x ו-x_content לשדות רב-לשונייםראו טבלאות רב-לשוניות

שכבת ה-DB (המחלקה DB) מציעה שאילתות גולמיות ובוני שאילתות. כלל חשוב: הבונים (DB::query, DB::update, DB::delete) מקבלים שמות טבלאות בלי הקידומת CRM_, ושאילתות גולמיות (DB::get_all, DB::get_row, DB::sql) דורשות את השם המלא עם הקידומת. פרטים ב-שכבת ה-DB וברשימת כל הטבלאות ב-כל הטבלאות.

שכבות מטמון#

שלוש שכבות עיקריות, וחשוב להבדיל ביניהן כשמשהו "לא מתעדכן":

  1. מטמון נתונים (cache_engine::get): קבצי *.chc.gz בתיקיית cache/ עם משך חיים לכל מפתח. רשימת המודולים, כתובות ה-SEO, ההפניות, הפלטפורמות והפרמטרים נשמרים כאן, ממשך של שעות ועד חודש.
  2. מטמון עמוד מלא: קבצי cache/<host>/pages/*.html.gz שנכתבים כשקונטרולר מבקש במפורש (cache_engine::cache_all_page($hours)). זמן התפוגה נשמר בזמן השינוי של הקובץ, והקובץ מוגש לפני שהניתוב והתבניות בכלל רצים (מטמון עמודים מלא).
  3. מטמון נכסים: JS, CSS ו-SCSS מקומפל ב-cache/<host>/ ובתיקיות המשנה שלו; Apache מגיש אותם ישירות כשהם קיימים. בנוסף, ל-Smarty יש תיקיית קומפילציה משלו (cache/Smarty/).

סקירה מלאה ב-איך המטמון עובד, ה-API ב-cache_engine API והניקוי ב-ניקוי ותחזוקה.

נקודות ההרחבה#

כל מה שאתר מוסיף נכנס דרך נקודה מוגדרת. לא צריך (ואסור) לעקוף את הליבה:

מהאיפההערות
עמוד חדשapplication/controllers/<name>.php + שורה ב-CRM_modulesהעמוד הראשון שלך
תצוגהapplication/views/*.tplנטענת דרך $this->view()
עיצוב כלליthemes/<name>/index.php + index.tplמחלקה TEMPLATE_<name> שיורשת מ-bgl_theme
קוד שרץ בכל בקשהapplication/includes/*.phpנטען בסדר אלפביתי, אחרי הניתוב, רק בצד הלקוח; לרישום אירועים, נכסים ו-hooks
פאנל ניהולapplication/admin/<name>.php + שורה ב-CRM_adminPanel_panelsמחלקה ADMINMODULE_<name>
קוד שרץ בכל בקשת ניהולapplication/admin/includes/*.phpהמקום לרישום כלי MCP עם AGENT_TOOLS::add_tool (כתיבת כלי MCP, MCP ב-WIZZO CMS)
אירועיםPAGE::bind("event", function($args){...})למשל SYSTEM_LOADED שנורה אחרי טעינת המערכת (PAGE: נכסים, מטא ואירועים)
עיבוד סופי של ה-HTMLPAGE::$parse_page_funcרץ גם על עמוד שהוגש מהמטמון

תכונות תכנון שכדאי להכיר#

הקוד של WIZZO CMS התפתח לאורך שנים, ולכן יש בו מוסכמות שונות מפרויקט PHP מודרני. מי שמכיר אותן חוסך זמן:

  • מצב גלובלי סטטי. CONFIG, PAGE, SEO ו-MISC::$GLOBALS מחזיקים מצב של הבקשה הנוכחית. אין מופע לבקשה, ולכן אין בידוד בין חלקי הקוד; מי ששומר ערך ב-PAGE::$theme משפיע על כולם.
  • בלי autoloader ובלי namespaces. מחלקות נטענות ידנית: הקולקשנים בלולאה ב-core.php, ספריות עם load->library, קונטרולרים עם require_once על ידי MODULE. לכן שם מחלקה גלובלי חייב להיות ייחודי, והתנגשות היא שגיאה קטלנית. ראו מוסכמות ושמות.
  • מטמון בקבצים. אין Redis או Memcached בליבה; כל המטמון הוא קבצים בדיסק, מה שעובד בכל אירוח אבל תלוי בהרשאות כתיבה לתיקיית cache/.
  • Smarty ו-eval. התבניות רצות על Smarty (הערך CONFIG_USER::$use_smarty = true). שני מצבים ישנים נשארו בקוד ("plain" ומצב eval של מחרוזות), ולא כדאי להשתמש בהם באתר חדש.
  • פלטפורמה לפי שם שרת. הליבה בוחרת את הפלטפורמה לפי SERVER_NAME, ולכן אותו קוד יכול לשרת כמה דומיינים.
  • עברית בהערות ובממשק. הערות ותוויות רבות בקוד כתובות בעברית ובאנגלית לסירוגין. שמות מזהים ומפתחות מסד נתונים באנגלית.
  • כלים לדיבוג. דיבוג ניתוב (?__router_trace=1) ו-אבחון ולוגים הם נקודת ההתחלה כשמשהו לא מתנהג כמצופה.

איפה ממשיכים#

מצאתם טעות או חוסר? תקנו את הדף או פתחו Issue בריפו. התיעוד נכתב מתוך הקוד של ליבה 5.0.115.