הוסטס - פורום אחסון האתרים הגדול בישראל

הוסטס - פורום אחסון האתרים הגדול בישראל (https://hosts.co.il/forums/index.php)
-   פורום תיכנות (https://hosts.co.il/forums/forumdisplay.php?f=14)
-   -   PHP וSQL - מערכת רב-לשונית (https://hosts.co.il/forums/showthread.php?t=83964)

Gal Shafrir 23-07-10 16:07

PHP וSQL - מערכת רב-לשונית
 
אהלן, חבר'ה.

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

הבעיה שלי היא כזו:
אני צריך לפתח מודול נוסף: מודול שפות.
באמצעות המודול ניתן יהיה לתרגם את האתר למספר שפות בלתי מוגבל,
בעוד שהשפות נשלפות מתוך טבלה במסד, לצורך העניין.

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

הציעו לי לעשות טבלה מקשרת בין תרגום לבין פריט במודול:
parentID - הפריט שרוצים לתרגם
itemID - הפריט המתורגם (להלן: התרגום עצמו)
module - כמובן, לאיזה מודול שייך התרגום (עמודים/מאמרים/...)
lang - קוד השפה (he/en וכו')

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


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

דוגמה לשליפת כל העמודים בשפה מסוימת:
PHP קוד:

    public function get_all($lang '')
    {
        
$sql "SELECT `translations`.`itemID`, `pages`.*
        FROM `pages`, `translations`
        WHERE `translations`.`parentID` = `pages`.`ID` AND `translations`.`lang`='{$lang}'
        AND `translations`.`module` = 'pages'"
;
        
        
$query $this->db->query($sql);
        
        
$pages $query->result_array();
        
        if (
count($pages) > 0)
        {
            foreach (
$pages as $key => $page)
            {
                
$sql "SELECT * FROM `pages` WHERE `ID` = '{$page['itemID']}'";
                
$q $this->db->query($sql);
                
                
$r $q->result_array();

                
$pages[$key]['name'] = $r[0]['name'];
                
$pages[$key]['content'] = $r[0]['content'];
                
$pages[$key]['title'] = $r[0]['title'];
            }
        }

        
/*$this->db->order_by('homepage', 'desc');
        $this->db->order_by('order', 'asc');    
        $query = $this->db->get('pages');*/
        
        
return $pages;
    } 

הקוד לדעתי לא יעיל, ועליי למצוא פתרון יותר יעיל מזה.

פתרון נוסף:
לשייך לכל מודול 2 טבלאות: אחת לתכנים ואחת לכל שאר הדברים
שצריך לשמור לגבי אותו הפריט (סטטוס, כתובת וכו').

אשמח לעזרה בנושא, זו פעם ראשונה שאני עושה דבר כזה.

תודה לעוזרים,
גל.

SarafC 23-07-10 16:19

אני לא חושב שהבנתי אותך במדוייק, אבל אם אתה רוצה לעבוד עם מספר שפות, למה לא לעבוד עם קבצי LANG?

Gal Shafrir 23-07-10 16:22

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

AlmogBaku 23-07-10 16:24

http://img707.imageshack.us/img707/9041/tblexitems.png

Gal Shafrir 23-07-10 16:30

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

AlmogBaku 23-07-10 16:59

אני מתכנת DB בד"כ ע"י mysql workbench

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

Gal Shafrir 23-07-10 17:33

אלמוג, יש שיטה דרך המסד ליצור את מה שכתוב בסכמה באנגלית מימין?
או דרך יעילה לעשות זאת בPHP?..

AlmogBaku 23-07-10 18:02

רשמתי שההתנהלות היא בצרוה כזו שאם הערך של השדה לא ריק הוא דורס את הערך של שדה האב, אם הערך ריק הוא יורש אותו מהאב.

כלומר:
אם בתרגום לא הכנסתי כותרת, הכותרת תהיה הכותרת של האב.

Gal Shafrir 23-07-10 19:10

ציטוט:

נכתב במקור על ידי Baku (פרסם 772534)
רשמתי שההתנהלות היא בצרוה כזו שאם הערך של השדה לא ריק הוא דורס את הערך של שדה האב, אם הערך ריק הוא יורש אותו מהאב.

כלומר:
אם בתרגום לא הכנסתי כותרת, הכותרת תהיה הכותרת של האב.

זה בדיוק מה שניסיתי לעשות,
אם תשים לב בדוגמת הקוד שנתתי כאן:
גם לאב יש שדה תוכן (אך הוא ריק), ולכן דרסתי אותו בלולאה.

אני מחפש דרך יעילה יותר לעשות את זה,
בלי לולאות מיותרות וכו'.

AlmogBaku 24-07-10 19:54

כי עשית שם משהו אחר לגמרי..
שוב- אתה צריך ליצור טבלאה אחת בכל הסיפור הזה.

תיצור פעולה רקורסיבית שמביאה לך את המידע הסופיע עם המידע(פעולה()-לוקחת נתונים. אם יש לו אבא, ממלאת את הנתונים הריקים בנתונים מפעולה())

Gal Shafrir 24-07-10 22:22

ציטוט:

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

תיצור פעולה רקורסיבית שמביאה לך את המידע הסופיע עם המידע(פעולה()-לוקחת נתונים. אם יש לו אבא, ממלאת את הנתונים הריקים בנתונים מפעולה())

אני לא בטוח שהבנתי אותך עד הסוף.
הפונק' צריכה להחזיר לי מידע לגבי כל הפריטים או לגבי פריט ספציפי אחד (שלו כמה תרגומים)?

AlmogBaku 25-07-10 13:26

ציטוט:

נכתב במקור על ידי gal shafrir (פרסם 772625)
אני לא בטוח שהבנתי אותך עד הסוף.
הפונק' צריכה להחזיר לי מידע לגבי כל הפריטים או לגבי פריט ספציפי אחד (שלו כמה תרגומים)?

אני מציע שהמתודה שלך תקבל מידע ותשחזר תמיד את הריק באופן רקורסיבי לפי האבות(כל עוד צריך).

PHP קוד:

get_item($id$fields="*"); 


Gal Shafrir 25-07-10 14:37

משהו בסגנון הזה?

PHP קוד:

    public function get_by_parent_recursive($lang ''$parentID 0$arr = array())
    {
        
$this->db->where('lang'$lang);
        
$this->db->where('parentID'$parentID);
        
$query $this->db->get('pages');
        
        
$results $query->result_array();
        
        if (
$query->num_rows() > 0)
        {
            
$results $results[0];
            
            
// Recall the function
            
$arr $this->get_by_parent_recursive('he'$results['ID'], $results);

            
// Merging the parent and it's child arrays
            //
            // while the page's settings related fields are taken from the parent's
            // and the content related fields from the child's
            
            
if (count($arr) > 0)
            {
                if (empty(
$results['content']))
                    
$results['content'] = $arr['content'];
                
                if (empty(
$results['title']))
                    
$results['title'] = $arr['title'];
                    
                if (empty(
$results['name']))
                    
$results['name'] = $arr['name'];
            }
        }
        
        return 
$results;
    } 


Gal Shafrir 26-07-10 11:47

סליחה על ההקפצה,
אבל אני לא מבין מה רע בשאילתא כזו:

PHP קוד:

$sql "SELECT `pages`.*, `contents`.*
FROM `pages`,`contents`
WHERE `contents`.`parentID` = `pages`.`ID` AND `contents`.`lang` = '{$lang}' AND `module` = 'pages'
ORDER BY `pages`.`homepage` DESC, `pages`.`order`"


אני מקבל בקלות את השדות שאני צריך.
במקרה שהטבלה pages לא מכילה שדות הקשורים לתוכן...

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

אז מה בעצם צריך להיות השיקול שלי?
אני חושב שהשיטה שלי יותר קלה לביצוע, יותר יעילה לא בטוח,
אז מה דעתכם?


כל הזמנים הם GMT +2. הזמן כעת הוא 22:32.

מופעל באמצעות VBulletin גרסה 3.8.6
כל הזכויות שמורות ©
כל הזכויות שמורות לסולל יבוא ורשתות (1997) בע"מ