סקירת פאנל הניהול

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

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

פאנל הניהול הוא אפליקציית עמוד יחיד (SPA) שנבנית מפאנלים: כל פאנל הוא מחלקת PHP אחת שמחזירה HTML, וכל כתובת {admin}/<panel>/<method> מפעילה מתודה אחת שלה. בדף הזה מוסבר איך כתובת הופכת לפאנל, איפה הקוד יושב, מה הטבלאות שמנהלות את התפריט וההרשאות, ומה שייך לליבה ומה לאתר.

{admin} הוא CONFIG::$admin_url, ו-system/ הוא תיקיית הליבה (api/core בריפו).

כתובת האדמין#

CONFIG::$admin_url הוא slug בלי לוכסנים (למשל admin), והוא נכנס כמו שהוא לביטוי רגולרי ב-ROUTER. הוא יחסי ועובד דרך <base href>, ולכן אל תשתמשו בו בכותרת Location או בקישור שיוצא מהאתר. קישור מוחלט בונים מ-CONFIG::$site_url (שמסתיים ב-/).

מיפוי כתובת לפאנל#

ROUTER מזהה כתובות אדמין לפי ארבעה דפוסים ומציב $_GET["module"], $_GET["pname"] ו-$_GET["id"]:

כתובתmodulepnameid
{admin}ריק (דף הבית)ריק
{admin}/newsnewsריק
{admin}/news/1newsריק1 (מספר)
{admin}/news/insertnewsinsert
{admin}/news/insert/1newsinsert1

pname ריק הופך ל-index בהמשך. בדפוס של שלושה קטעים (module/pname/id) ה-id הוא כל מה שאחרי ה-pname, ולא חייב להיות מספר.

אם הוגדרה רשימת מדינות מותרות (admin_countries), גישה מחוץ לה מופנית לעמוד הבית של האתר. הבדיקה מדולגת כשהבקשה מגיעה מאותו שרת (REMOTE_ADDR שווה ל-SERVER_ADDR) ולכתובות של Wizzo.

מה קורה בבקשה: AdminModule::GetPageContent#

AdminModule (system/libraries/AdminModule.php) מריץ את הפאנל לפי הסדר הזה:

  1. טוען את שורת הפאנל מ-CRM_adminPanel_panels ואת האפשרויות שלו מ-panels_options.
  2. פאנל של Wizzo Market (מוגדר ב-system/market_settings.json) מופנה ל-wizzo_market?tool=....
  3. טוען את קובץ הפאנל (require_once) ובודק אם המחלקה מגדירה skip_permission_check.
  4. דוחה ל-404 (ERRORPAGE) כשאין שורה בטבלה או שאין הרשאה, או כש-perm_developer = 1 והמשתמש אינו מפתח. פרטים ב-הרשאות.
  5. רושם צפייה בפאנל (admin_panel_views::record_view), שמזין את "הפאנלים הנצפים ביותר" בבית.
  6. יוצר new ADMINMODULE_<module>(), קובע pname (ברירת מחדל index), בודק ש-method_exists, ומחזיר את התוצאה של $mdl->Wrapper($mdl->$pname()).

כל הפאנלים נטענים דרך GetPageContent, וגם דף הבית (home) הוא רק פאנל כזה שלא צריך שורה בטבלה.

מצבי תצוגה: pmode#

פרמטר pmode קובע כמה מהעמוד חוזר:

pmodeתוצאה
ריקעמוד מלא (theme admin_panel, או admin_login כשלא מחוברים)
innerרק תוכן הפאנל. adminMovePage טוענת אותו לתוך #mainframe
empg"empty page": תגובת JSON או HTML חלקי, למשל שמירת טופס ופעולות של טבלה

הפאנל שולח לדפדפן מידע דרך כותרות תגובה: breadcrumbs (דרך MISC::breadcrumbs($list)), add_action, scripts ו-scripts_ver, AI-New-ID, AI-Form-Error, AI-Error. הדפדפן מגיב להן ב-funcs.js של ה-theme.

איפה יושב קוד פאנל#

מיקוםתוכן
application/admin/<name>.phpפאנל של האתר: class ADMINMODULE_<name>
system/admin/<name>.phpפאנל מובנה של הליבה (ראו פאנלים מובנים)
application/admin/includes/נטען אוטומטית בכל בקשת אדמין: מקום למחלקות FormInput_* מותאמות ופונקציות עזר
system/libraries/AdminModule, panel_table, forms/ (הטפסים ושדותיהם)
system/collections/ADMIN.phpהתחברות, סשנים והרשאות
system/themes/admin_panel/מעטפת ה-SPA, התפריט ו-funcs.js
הערה

אם קיימים באותו שם קובץ בשתי התיקיות, הקובץ של הליבה (system/admin/) מנצח את זה של application/admin/. אל תקראו לפאנל שלכם בשם של פאנל מובנה.

הטבלאות שמריצות את התפריט#

כל הטבלאות בקידומת CRM_; ה-builder של DB מקבל את השם בלי הקידומת.

טבלהתפקיד
adminPanel_panels_categoriesקטגוריות התפריט: id, name, ord
adminPanel_panelsפאנל בתפריט: id, panel_name, text, module_link, category, deletable, ord, pic, icon, extra_perms, perm_developer, stats_views, view_count
adminPanel_panels_optionsתת-פעולות של פאנל: id, panelId, name, filename, attribute, ord, icon
adminPanel_admins_groupsקבוצות הרשאה: id, name, perms
adminPanel_adminsהמנהלים (ראו התחברות)

panel_name שווה לשם הקובץ ב-application/admin/ (בלי .php), ו-module_link ריק לפאנלים שמגובים בקוד. ראו את הסכמה המלאה ב-טבלאות.

הוספת קובץ פאנל לא מספיקה כדי שהוא יופיע: חייבים שורה ב-adminPanel_panels. איך רושמים אותה מפורט ב-בניית פאנל חדש.

הבית: דף הפתיחה#

פאנל home מציג קיצורי דרך ותיבות. אתם יכולים להוסיף אליהם מקוד האתר:

// עד 6 קיצורים, החדש נכנס ראשון
admin_home::push_quick_action([
    "label" => "מאמרים",
    "icon"  => "📰",
    "url"   => CONFIG::$admin_url . "/articles",
]);

// תיבה בדף הבית; $position מאפשר מיקום מסוים, ברירת מחדל: בסוף
admin_home::push_box([
    "label"   => "סיכום מכירות",
    "content" => function () {
        return "<p>תוכן התיבה</p>";
    },
]);

המבנה של פריט קיצור (label, icon, url) זהה לברירות המחדל של המחלקה admin_home. הקיצורים מסוננים לפי הרשאה: קיצור לפאנל שאין למנהל גישה אליו לא מוצג.

ליבה מול אתר#

  • ליבה (system/): מתעדכנת ב"עדכון גרסה" ואסור לערוך אותה באתר (ראו עדכונים). כל מה שבה זהה בכל האתרים.
  • אתר (application/): הפאנלים, הקונטרולרים והשדות שלכם. עדכון גרסה לא נוגע בהם.

כדי לשנות התנהגות של פאנל מובנה, אל תערכו אותו: צרו פאנל משלכם בשם אחר, או הרחיבו דרך נקודות ההרחבה (application/admin/includes/, admin_home::push_box, admin_home::push_quick_action).

שימו לב
Smarty בפאנלים לא עושה escape אוטומטי, ופאנלים מחזירים מחרוזות HTML. כל ערך שמגיע ממשתמש חייב לעבור htmlspecialchars לפני ההדפסה (ראו CSRF, XSS ו-SQLi).

ראו גם#

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