יצירת הרחבות

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

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

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

1. רכיב אפליקציה

רכיב אפליקציה צריך ליישם את הממשק IApplicationComponent או להיות תת-מחלקה (לירוש) של CApplicationComponent. המתודה העיקרית שצריך ליישם הינה IApplicationComponent::init שבה הרכיב מבצע עבודות אתחול. מתודה זו רצה לאחר היצור של הרכיב והמאפיינים ההתחלתיים (המוגדרים בהגדרות האפליקציה) מצורפים.

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

2. התנהגות

בכדי ליצור התנהגות, יש ליישם את הממשק IBehavior. לנוחות, Yii מספקת מחלקת בסיס CBehavior אשר כבר מיישמת את הממשק הנחוץ ומספקת כמה מתודות שימושיות נוספות. תת-מחלקות צריכות ליישם את המתודות הנוספות שעומדות להיות זמינות לרכיבים אליהם הם יצורפו.

כשמפתחים התנהגות עבור CModel ו CActiveRecord, ניתן להרחיב מהמחלקות CModelBehavior ו CActiveRecordBehavior, בהתאמה. מחלקות בסיס אלו מציעות אפשרויות נוספות שמיועדות ספציפית ל CModel ו CActiveRecord. לדוגמא, המחלקה CActiveRecordBehavior מיישמת סט של מתודות המגיבות לאירועים אשר מתבצעים במחלקת ActiveRecord.

הקוד הבא מציג דוגמא להתנהגות של ActiveRecord. כשההתנהגות מצורפת לאובייקט של AR וכשהאובייקט AR נשמר על ידי קריאה למתודה save(), הוא אוטומטית יגדיר את המאפיינים create_time ו update_time עם הזמן הנוכחי בשרת.

class TimestampBehavior extends CActiveRecordBehavior
{
    public function beforeSave($event)
    {
        if($thisownerisNewRecord)
            $thisownercreate_time=time();
        else
            $thisownerupdate_time=time();
    }
}

3. וידג'ט

וידג'ט צריך להיות תת מחלקה של CWidget או מחלקות היורשות ממנה.

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

class MyTabView extends CTabView
{
    public function init()
    {
        if($thiscssFile===null)
        {
            $file=dirname(__FILE__).DIRECTORY_SEPARATOR.'tabview.css';
            $thiscssFile=Yii::app()getAssetManager()publish($file);
        }
        parent::init();
    }
}

בקוד למעלה, אנו דורסים את המתודה CWidget::init ומציבים למאפיין CTabView::cssFile את סגנון CSS ברירת המחדל במידה והוא לא הוגדר ספציפית. אנו מוסיפים את קובץ הסגנון תחת התיקיה הנוכחית בה נמצאת המחלקה MyTabView בכדי שיהיה ניתן לאחד אותם כהרחבה. מאחר וקובץ הסגנון הוא לא נגיש לווב יהיה צורך בלפרסם אותו בקובץ נכס.

בכדי ליצור וידג'ט חדש מהתחלה, אנו בעיקר צריכים ליישם שני מתודות: CWidget::init ו CWidget::run. הראשונה רצה כשאנו משתמשים ב this-»beginWidget$ בכדי להוסיף את הוידג'ט לתצוגה, והשני רץ ברגע שאנו קוראים ל this-»endWidget$. במידה ואנו רוצים לתפוס את התוכן הנמצא בין שני המתודות הללו, אנו יכולים להתחיל בפקודת תפסית תצוגה במתודה CWidget::init ולקבל את התוכן שנתפס על ידי CWidget::run להמשך העיבוד.

בדרך כלל וידג'ט דורש הוספה של קבצי CSS, JS וקבצים נוספים בעמוד אשר הוידג'ט משתמש בהם. אנו קוראים לקבצים אלו נכסים מאחר והם נשארים ביחד עם המחלקה של הוידג'ט ובדרך כלל לא ניתן לגשת אליהם דרך ממשק הווב. בכדי לאפשר גישה לקבצים אלו דרך הווב, אנו צריכים לפרסם אותם לתיקיה בה יש גישה לווב בעזרת CWebApplication::assetManager, כפי שמוצג בקוד למעלה. חוץ מזה, שבמידה ואנו רוצים לפרסם קובץ CSS או JS אנו צריכים לרשום אותו על ידי שימוש במחלקה CClientScript.

class MyWidget extends CWidget
{
    protected function registerClientScript()
    {
        // ..פרסום קבצי CSS ו JS כאן...
        $cs=Yii::app()clientScript;
        $csregisterCssFile($cssFile);
        $csregisterScriptFile($jsFile);
    }
}

וידג'ט יכול להכיל קבצי תצוגה משלו. במקרה זה, יש ליצור תיקיה בשם views תחת התיקיה המכילה את קובץ המחלקה של הוידג'ט, ויש לשמור את כל קבצי התצוגה של הוידג'ט בתיקיה זו. במחלקה של וידג'ט, בכדי לטעון קובץ תצוגה של הוידג'ט, יש להשתמש ב $this-»render('viewName'), בדומה למה שעושים בקונטרולר.

4. פעולה

מחלקת פעולה צריכה להיות תת-מחלקה של CAction או מחלקות היורשות ממנה. המתודה העיקרית שצריך ליישם לפעולה הינה IAction::run.

5. פילטר

פילטר צריך להיות תת מחלקה של CFilter או מחלקות היורשות ממנה. המתודות העיקריות שצריך ליישם לפילטר הם CFilter::preFilter ו CFilter::postFilter. הראשון רץ לפני שהפעולה בקונטרולר מתבצעת בזמן שהשני לאחר הפעולה.

class MyFilter extends CFilter
{
    protected function preFilter($filterChain)
    {
        // לוגיקה שרצה לפני שהפעולה בקונטרולר רצה
        return true; // יש להחזיר false במידה ורוצים לבטל את הרצת הפעולה
    }
 
    protected function postFilter($filterChain)
    {
        // לוגיקה שרצה לאחר הרצת הפעולה בקונטרולר
    }
}

הפרמטר filterChain$ הוא אובייקט של CFilterChain המכיל מידע אודות הפעולה בקונטרולר שכרגע עוברת בתוך הפילטר.

6. קונטרולר

קונטרולר המופץ בתור הרחבה המחלקה שלו צריכה להיות תת של CExtController, במקום CController. הסיבה העיקרית הינה ש CController מניח שקבצי התצוגה של הקונטרולר נמצאים תחת application.views.controllerID, בזמן ש CExtController מניח שקבצי התצוגה של הקונטרולר נמצאים תחת התיקיה views שהינה תת תיקיה של התיקיה בה נמצא קובץ המחלקה של הקונטרולר. לכן, קל יותר להפיץ את הקונטרולר מאחר וקבצי התצוגה שלו נשארים ביחד עם קובץ המחלקה של הקונטרולר.

7. ולידטור (אימות נתונים)

ולידטור צריך להיות תת-מחלקה של CValidator וליישם את המתודה CValidator::validateAttribute.

class MyValidator extends CValidator
{
    protected function validateAttribute($model,$attribute)
    {
        $value=$model$attribute;
        if($value has error)
            $modeladdError($attribute,$errorMessage);
    }
}

8. מסוף פקודות

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

class MyCommand extends CConsoleCommand
{
    public function run($args)
    {
        // הפרמטר היחידה בפונקציה זו מחזיר מערך עם המידע שהוזן לפקודה
    }
 
    public function getHelp()
    {
        return 'הסבר כיצד להריץ פקודה זו';
    }
}

9. מודול

אנא קרא את החלק אודות מודולים המסביר כיצד לייצר מודול.

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

10. רכיב כללי

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

«div class="revision"»$Id: extension.create.txt 1423 2009-09-28 01:54:38Z qiang.xue $«/div»

Be the first person to leave a comment

Please to leave your comment.