פרמטרים ומילון שפות

PARAMS ו-LANGS: טבלת ההגדרות CRM_params והמילון הרב-לשוני CRM_langs_words, איך קוראים וכותבים אותם מהקוד ומהאדמין, איך המטמון עובד ומתי מנקים אותו.

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

שתי מחלקות קטנות נושאות את ההגדרות שנערכות בלי לגעת בקוד. PARAMS היא טבלת מפתח וערך של הגדרות אתר (תבנית דוא"ל עוטפת, אסימוני שירותים, דגלים), ו-LANGS היא מילון של מילים וטקסטים קבועים בכמה שפות. בעמוד הזה תראו איך שתיהן נטענות, איך קוראים אותן ושומרים אליהן, ומתי צריך לנקות מטמון כדי שהשינוי יופיע. פירוט הסכמות והמפתחות מופיע ברפרנס פרמטרים ושפות.

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

PARAMS: הגדרות מפתח-ערך#

איך נטען#

בתחילת כל בקשה PAGE::load קורא ל-PARAMS::init(). הפונקציה טוענת את כל השורות של CRM_params מהמטמון (מפתח params, תוקף 30 יום, cache_engine::get("params", ..., 24*30, false)) ושומרת אותן במערך סטטי בזיכרון. מכאן, קריאה של פרמטר במהלך הבקשה אינה פונה למסד הנתונים.

קריאה וכתיבה בזיכרון#

פונקציהתיאור
PARAMS::get($key)הערך כמחרוזת, או "" אם המפתח לא קיים. אין הבחנה בין "לא קיים" ל"ריק"
PARAMS::set($key, $value)מגדיר ערך בזיכרון בלבד, לבקשה הנוכחית. לא נכתב למסד ולא למטמון
PARAMS::GetArray($onlyWords = false)שבורה, ראו אזהרה
$tpl = PARAMS::get("mail_tpl");
if ($tpl === "") {
    // אין תבנית עוטפת, ממשיכים בלי
}

if (PARAMS::get("poolse_mail") === "0") {
    // המפתח קיים והערך "0" (שימו לב להשוואת מחרוזות)
}

בתבניות Smarty אפשר לקרוא לאותה פונקציה ישירות, כמו שעושה תבנית הליבה views/admin/sqllog.tpl:

{if PARAMS::get('log_sql') == '1'}הרישום פעיל{else}הרישום כבוי{/if}
שימו לב
GetArray לא עובדת הפונקציה מפנה ל-self::$arrWords, שלא קיים במחלקה PARAMS (המילים נמצאות ב-LANGS). קריאה אליה גורמת לשגיאה קטלנית. כדי לקבל את כל המילים השתמשו ב-LANGS::get_words_array().

כל הערכים הם מחרוזות
value הוא TEXT, ולכן PARAMS::get תמיד מחזירה מחרוזת. דגל בוליאני נשמר כ-1 או 0, ומשווים אליו כמחרוזת. מבנה מורכב נשמר כ-JSON ומפוענח בקוד.

הטבלה CRM_params#

עמודהמשמעות
idמזהה
sysNameהמפתח (ייחודי, עד 100 תווים)
valueהערך (TEXT)
descriptionתיאור חופשי, מוצג בפאנל
perm_developer1 מסתיר את השורה ממנהלים שאינם מפתחים בפאנל Params

מפתחות שהליבה עצמה משתמשת בהם:

מפתחשימוש
attaches_versionמספר גרסה לנכסים סטטיים, עולה בניקוי מטמון (ראו צינור הנכסים)
log_sql1 מפעיל רישום שאילתות (ראו דיבוג מסד נתונים)
cron_runner_token, cron_runner_heartbeatטוקן ודופק של משימות מתוזמנות
mail_tplנתיב תבנית עוטפת לדוא"ל
poolse_mail, poolse_mail_exclude, poolse_api_key, poolse_api_urlהגדרות POOLSE (ראו דוא"ל)
file_manager_readonly, file_manager_extra_roots, file_manager_show_sensitiveמנהל הקבצים (ראו מנהל קבצים)
seo_*, todo_*, bot_api_secretמערכות SEO, אינטגרציות וסוכן ה-AI

עריכה בפאנל#

הפאנל {admin}/Params מציג את השורות (קודם perm_developer ואחר כך לפי sysName), ומאפשר עריכת הערך ישירות בטבלה. עריכה, הוספה ומחיקה מנקות את מטמון params אוטומטית. מי שאינו מפתח (ADMIN::is_developer()) רואה רק שורות עם perm_developer = 0, ולא רואה את עמודת ההרשאה.

שימו לב
perm_developer מסתיר, לא מצפין הערכים נשמרים בטקסט גלוי במסד הנתונים. הדגל מסתיר שורה מתצוגת הפאנל בלבד. אין להשתמש ב-CRM_params ככספת: סיסמאות ומפתחות API ישמרו במקום שאפשר להגביל גישה אליו, ולא בשורה שכל גיבוי של המסד יכלול (ראו הקשחה).

כתיבה מהקוד#

כתיבה מהקוד היא עדכון שורה ואחריו ניקוי מטמון. בלי הניקוי, אחרי עד 30 יום (או עד הניקוי הבא) הבקשות ימשיכו לקבל את הערך הישן.

function save_param($name, $value, $description = "")
{
    $row = DB::get_val("params", ["sysName" => $name]);

    $u = DB::update("params")->set("value", (string)$value);
    if ($row) {
        $u->update((int)$row["id"]);
    } else {
        $u->set("sysName", $name)
          ->set("description", $description)
          ->set("perm_developer", 0);
        $u->insert();
    }

    cache_engine::remove("params");
    PARAMS::set($name, (string)$value);   // גם בבקשה הנוכחית
}

ה-builder מקבל את שם הטבלה בלי CRM_ ומטפל ב-escape (ראו בנאי שאילתות). כשמוסיפים פרמטר חדש כחלק מהתקנה, עדיף INSERT ... ON DUPLICATE KEY UPDATE, כי sysName ייחודי:

INSERT INTO CRM_params (sysName, value, description, perm_developer)
VALUES ('my_feature_enabled', '1', 'הפעלת הפיצ''ר החדש', 0)
ON DUPLICATE KEY UPDATE description = VALUES(description);
ברירת מחדל בקוד
PARAMS::get מחזירה "" כשהמפתח חסר, ולכן כתבו את הקוד כך שמחרוזת ריקה היא ברירת המחדל הסבירה: $limit = (int)PARAMS::get("my_limit") ?: 20;.

LANGS: מילון הממשק#

איך נטען#

בהמשך אתחול הבקשה, אחרי PARAMS::init() וטעינת ההקשר של העמוד, PAGE::load קורא ל-LANGS::init_words(). הפונקציה טוענת את כל המילים בשפה הנוכחית (CONFIG::$lang) מהמטמון words_lang<N> (תוקף 4 שעות), ושומרת במערך בזיכרון. הטעינה היא DB::query("langs_words") עם השדות sysName, value; הצטרפות הערכים לשפה נעשית אוטומטית דרך טבלת התוכן (ראו מסד נתונים רב-לשוני).

השפה היא מזהה פלטפורמה (CRM_platforms.id, ראו פלטפורמות ורב-לשוניות), ולכל פלטפורמה מילון משלה.

הטבלאות#

טבלהעמודות
CRM_langs_wordsid, sysName (המפתח, למשל EDIT), group_id
CRM_langs_words_contentid, parentId (מצביע ל-langs_words.id), langId (פלטפורמה), value (HTML). הצירוף parentId, langId ייחודי
CRM_langs_words_groupsid, name: קבוצות לארגון המילים בפאנל

קריאה#

פונקציהתיאור
LANGS::get_word($key, $lang = false)בלי $lang: המילה בשפה הנוכחית מהזיכרון, או "" אם המפתח חסר. עם $lang: שאילתה למסד של המילה בשפה אחרת (מזהה פלטפורמה)
LANGS::translate($val)מחפש $val כ-ערך במילון (array_search רופף) ומחזיר את הערך שנמצא. בפועל התוצאה זהה לקלט, ראו הערה
LANGS::set_word($key, $value)מגדיר מילה בזיכרון בלבד, לבקשה הנוכחית
LANGS::init_words()טעינה מהמטמון או מהמסד (נקראת מ-PAGE::load)
LANGS::get_words_array()כל המילים כמערך sysName => value
echo LANGS::get_word("EDIT");                  // בשפת הבקשה הנוכחית
echo LANGS::get_word("EDIT", 2);               // בשפה 2, שאילתה למסד בכל קריאה

בתבניות Smarty:

<button>{LANGS::get_word('EDIT')}</button>
מילה חסרה מחזירה מחרוזת ריקה
get_word בלי $lang מחזירה "" כשהמפתח לא קיים, ולא את שם המפתח. כך ממשק עם מפתח חסר נראה ריק ולא שבור. הוסיפו את המפתח לכל השפות, או בדקו תוצאה ריקה בקוד.

שימו לב
get_word עם שפה היא שאילתה בכל קריאה הקריאה עם $lang לא משתמשת במטמון, ופונה למסד בכל פעם. בלולאה על הרבה מילים זה יוצר עומס. כשצריך הרבה מילים בשפה אחרת, בצעו שאילתה אחת על CRM_langs_words_content לפי langId. בנוסף, אם המילה לא קיימת באותה שפה, הפונקציה לא בודקת את התוצאה לפני שהיא ניגשת לשדה value, ויכולה להפיק אזהרת PHP.

הערה
translate לא מתרגמת היא מחפשת את הטקסט שקיבלה בין הערכים של המילון ומחזירה את הערך שמצאה, כלומר את אותו טקסט (או את הקלט עצמו כשלא נמצא). היא סורקת את כל המילון בכל קריאה. לתרגום לפי מפתח השתמשו ב-get_word.

עריכה#

מילים נערכות בפאנל הניהול הוותיק ui_langs_legacy, שבו קבוצות (insertGroup), מילים (insertWord) ורשימת מילים בקבוצה. כל שמירה מנקה את מטמון המילים (cache_engine::remove("words")), מרעננת אותו (LANGS::init_words()) ומפעילה את האירוע words_update (PAGE::trigger).

כתיבה מהקוד#

הוספה של מילה חדשה היא שורה ב-CRM_langs_words ושורת ערך לכל שפה ב-CRM_langs_words_content. בסקריפט התקנה אפשר לכתוב את זה כך:

INSERT INTO CRM_langs_words (sysName, group_id) VALUES ('CHECKOUT_TITLE', 1);

INSERT INTO CRM_langs_words_content (parentId, langId, value)
SELECT id, 1, 'סיכום הזמנה' FROM CRM_langs_words WHERE sysName = 'CHECKOUT_TITLE' LIMIT 1
ON DUPLICATE KEY UPDATE value = VALUES(value);

ואחרי כל שינוי, מנקים את המטמון:

cache_engine::remove("words");

הפרמטר הוא קידומת של שם קובץ המטמון, ו-words תופס את words_lang1, words_lang2 וכן הלאה בכל תיקיות המטמון.

כתבו מילון, לא מחרוזות בקוד

טקסט שמוצג למשתמש ושייך לממשק, ולא לתוכן של דף, שייך למילון כדי שיהיה אפשר לתרגם ולערוך אותו בלי קוד (ראו תקן קוד).

מתי מנקים מטמון#

שינוימה לעשות
ערך ב-CRM_params דרך הפאנלכלום, הפאנל מנקה
ערך ב-CRM_params מ-SQL או מקודcache_engine::remove("params")
מילה דרך ui_langs_legacyכלום, הפאנל מנקה
מילה מ-SQL או מקודcache_engine::remove("words")
שינוי אינו מופיעודאו שניקוי המטמון רץ על אותו שרת ותיקיית מטמון, ראו ניהול מטמון

מנגנון המטמון שומר ערך רק אם מספר שגיאות ה-DB לא עלה בזמן בנייתו, כך שתקלה רגעית לא "נתקעת" במטמון עד פקיעת התוקף (ראו API המטמון).

ראו גם#

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