תוכן שמשתנה לפי שפה (כותרת, תיאור, טקסט) לא נשמר באותה טבלה עם הנתונים הקבועים. לכל טבלה כזאת יש "טבלת תוכן" תאומה, וה-builder של DB מחבר ביניהן לבד. הדף מסביר את המבנה, איך קוראים וכותבים שדות מתורגמים, ומתי ה-join האוטומטי מפתיע.
בעמוד הזה system/ הוא תיקיית הליבה הפרוסה (= api/core בריפו) ו-{admin} הוא CONFIG::$admin_url של האתר.
המבנה#
לטבלה CRM_<t> (ה"conf": שדות קבועים כמו id, ord, מצב) יש תאומה CRM_<t>_content עם השדות המתורגמים ושתי עמודות קישור:
| עמודה | משמעות |
|---|---|
parentId | ה-id של השורה ב-CRM_<t> |
langId | מזהה השפה: CRM_platforms.id |
שורה אחת בטבלה הראשית ושורה אחת לכל שפה בטבלת התוכן. "שפה" כאן היא פלטפורמה (CRM_platforms): CONFIG::$lang הוא מזהה הפלטפורמה הנוכחית (CONFIG::$platform_data["id"]). הפלטפורמה נבחרת לפי $_SERVER['SERVER_NAME'], אחר כך לפי allowed_domains, ובלית ברירה השורה הראשונה. הרשימה נטענת ב-CONFIG::init() ונשמרת במטמון 30 יום (platforms). ראו פלטפורמות ורב-לשוניות.
קריאה#
ה-builder בודק אם הטבלה CRM_<t>_content קיימת (DB::is_table_exists), ואם כן מחבר אותה אוטומטית ומסנן לפי השפה:
$page = DB::query("pages", ["id" => 12])->get_row();
// $page["title"] מגיע מ-CRM_pages_content, $page["noDelete"] מ-CRM_pages
ה-SQL שנבנה הוא בקירוב:
SELECT * FROM CRM_pages_content tData, CRM_pages tConf
WHERE true AND tData.parentId = tConf.id AND tData.langId = <lang> AND tConf.id = '12'
בחירת שפה אחרת: הארגומנט הרביעי של DB::query.
$en = DB::query("pages", ["id" => 12], "", $englishPlatformId)->get_row();
ה-join הוא למעשה INNER JOIN. שורה ב-CRM_pages שאין לה שורת תוכן בשפה המבוקשת פשוט לא תחזור מהשאילתה, בלי שגיאה. אם רשימה "חסרה" ערכים רק באתר בשפה מסוימת, בדקו קודם שיש להם שורת _content בשפה הזאת.
כשכותבים SQL גולמי אין join אוטומטי: מחברים בעצמכם.
$rows = DB::get_all(
"SELECT c.id, t.title FROM CRM_pages c
JOIN CRM_pages_content t ON t.parentId = c.id AND t.langId = " . (int)CONFIG::$lang
);
כתיבה#
set_var עם הארגומנט השלישי "content" כותב לטבלת התוכן:
$ins = DB::update("pages");
$ins->set_var("noDelete", 0); // conf
$ins->set_var("title", "כותרת", "content"); // content
$ins->insert(); // יוצר גם את שורת התוכן בשפה הנוכחית
$id = $ins->new_id;
$up = DB::update("pages");
$up->set_var("title", "Title", "content");
$up->update($id); // יוצר שורת תוכן אם חסרה
מה קורה בפועל:
insert()יוצרת את שורת התוכן עםlangId = CONFIG::$lang, כלומר בשפה הנוכחית בלבד. תרגום לשפות נוספות נעשה בקריאה נפרדת בכל שפה (החלפתCONFIG::$langאו כתיבת שורה ידנית).update($id)מעדכנת את שורת התוכן של(parentId, langId), ויוצרת אותה אם אינה קיימת.- מחיקה עם
DB::deleteמסירה גם את כל שורות התוכן של ה-id.
מתודת copyToAllLangs ב-DB_UPDATE_CLASS מיועדת להעתיק תוכן לכל השפות, אבל היא שבורה: היא קוראת מהטבלה הישנה CRM_langs, ובשורות השפה new_id ריק כי הרקורסיה רצה לפני ה-INSERT הראשי. אל תסתמכו עליה.
טבלאות בשם לא סטנדרטי#
ברירת המחדל היא <table>_content עם עמודת קישור parentId. טבלה שבנויה אחרת מוגדרת עם ChangeContentTable:
$u = DB::update("my_table");
$u->ChangeContentTable("my_table_lang", "item_id");
ובאובייקט שאילתה אפשר לשנות את contentTable ואת queryKey.
מטמון רשימת הטבלאות#
זיהוי טבלת התוכן נשען על DB::is_table_exists, שמחזיקה את רשימת כל הטבלאות במטמון 7 ימים (המפתח table_list, גלובלי לכל הדומיינים). מי שיוצר טבלת _content חדשה בזמן ריצה צריך למחוק את המפתח, אחרת ה-builder לא "יראה" אותה:
cache_engine::remove("table_list");
ניקוי מהפאנל (ראו ניקוי ותחזוקה) או קריאה ל-system/Tools/delete_cache מנקים גם table_list.