הנוהל הזה הוא לקרינגל (או למפתח עם גישה ל-agent_mcp) שמקבל בקשה כמו "תעביר את הבלוג מ-WordPress לאתר". הוא עובד עם אותו מנוע כמו אשף הייבוא. את מה שכתוב שם (המיפוי, המקורות, המתאמים) לא חוזרים לפרט כאן.
{admin} הוא CONFIG::$admin_url של האתר. הכלים זמינים מליבה 5.0.152, והאשף מליבה 5.0.173.
הכלים עובדים בשם מנהל הבוט של agent_mcp, ולכן אין בהם בדיקת הרשאה של אדם. הבקשה של האדם היא האישור, והוא צריך להיות מי שרשאי לייבא באתר (בעלים או עורך).
הבדיקות שהאשף עושה בשם המנהל המחובר (עריכה בפאנל, פרסום, שדות חסומים, ראו מי רשאי) לא רצות בכלים. לכן: כשהאדם שביקש לא רשאי לפרסם בסוג היעד, מייבאים רק טיוטות ("statuses": ["draft", "pending"] במיפוי), ושדות שהוא לא רשאי לשנות לא ממפים.
1. ניתוח#
import_analyze { "url": "https://old-site.co.il/export.xml" }
import_analyze { "path": "uploads/export.xml" }
url הוא כתובת שהשרת מוריד ממנה, path הוא קובץ .xml בתוך תיקיית האתר. התשובה היא job_id ודוח (report). הדוח לא כותב שום תוכן. מה לקרוא בו:
report.counts: כמה רשומות, קבצים מצורפים וכותבים יש;report.types: לכל סוג ב-WordPress, כמה רשומות, באילו סטטוסים, אילו שדות מותאמים (עם דוגמאות) ואילו מונחים, ו-proposed: מבנה מוצע לסוג חדש ורשומת מיפוי מוכנה;- מה לא יעבור: קודים קצרים לא מוכרים, בלוקים של Gutenberg, תוכן שינוקה.
אחרי הניתוח מספרים לאדם במשפט או שניים מה יש בקובץ ומה לא יעבור, לפני שבונים משהו.
2. יעד לכל סוג#
לכל סוג שמייבאים מחליטים: סוג קיים באתר, או סוג חדש.
- סוג קיים.
panelהוא הפאנל שלו. בודקים את שמות השדות בטופס שלו (הקוד של הפאנל, או הכליadmin_schemaשלagent_mcp). - סוג חדש. בונים אותו באשף:
admin_loginפותח דפדפן מחובר כמנהל הבוט,{admin}/wp_importפותח את המשימה (job_id) מהרשימה, ובשלב היעד בוחרים "סוג חדש". האשף מציג את המבנה המוצע: עורכים שמות, כותרות, סוגי שדות ומקורות, ובונים. הבנייה מחזירה רשומת מיפוי מוכנה. בסוף סוגרים את הדפדפן ו-admin_logout. - סוג שצריך קוד (קטגוריות בטבלה משלהן, שדות מחושבים): בונים את הסוג כרגיל, וכותבים מתאם ייבוא ב-
application/libraries/בריפו של האתר, ופורסים אותו לפני ההרצה.
מליבה 5.0.174 הניתוח מציע את המפתחות המוכרים של WooCommerce ושל The Events Calendar (_price, _sku, _stock, תאריכי מבצע ואירוע) כשדות בשם קריא, ו-auto מחבר אותם לבד לשדה באותו שם. כל מפתח אחר עם קו תחתון ממפים במפורש עם meta:<key>. הרשימה המלאה ב-ייבוא מ-WordPress. מתאם צריך רק ערך מחושב, למשל מחיר המבצע כשיש אחד ואחרת המחיר הרגיל.
3. הרצת ניסיון#
import_run { "job_id": 12, "dry_run": true, "mapping": { "types": { "post": { "panel": "articles", "fields": { "image": "featured_image" } } } } }
הרצת ניסיון לא שומרת כלום ולא מורידה מדיה. היא מחזירה, לשלוש הרשומות הראשונות, מה הטופס היה מקבל, אילו קבצים היו מורדים ואילו אזהרות היו. from מתחיל ממקום אחר בקובץ. מתקנים את המיפוי עד ששדות הדוגמה נכונים.
4. הרצה#
import_run { "job_id": 12, "mapping": { ... } }
import_run { "job_id": 12 }
הקריאה הראשונה שומרת את המיפוי על המשימה. כל קריאה מייבאת מנה (ברירת מחדל 25 רשומות, או עד שנגמר זמן הקריאה, time_budget, ברירת מחדל 100 שניות) ומחזירה status. כל עוד הוא running קוראים שוב עם אותו job_id, בלי מיפוי. כשהוא done ההרצה גמורה.
- המשימה ממשיכה מאיפה שעצרה, גם אחרי הפסקה ארוכה או קריאה שנכשלה באמצע.
- שתי קריאות במקביל לאותה משימה: השנייה נדחית.
restart: trueמתחיל מהרשומה הראשונה ומעדכן את מה שכבר יובא. כך מתקנים מיפוי אחרי הרצה.
5. בדיקה ודיווח#
import_status { "job_id": 12 }
מחזיר את ההתקדמות, את הספירה לכל סוג ולכל מצב (created, updated, skipped, failed, warning), עד 30 בעיות אחרונות עם הסיבה שלהן, וסוף היומן של המשימה. בלי job_id הוא מחזיר את 20 המשימות האחרונות.
לפני הדיווח לאדם:
- פותחים שתי רשומות מיובאות באתר ובודקים כותרת, תוכן, תמונה ותאריך.
- פותחים כתובת ישנה אחת ובודקים שהיא מפנה לחדשה. כשהסוג חדש ואין לו בקר אתר, ההפניות שמורות אבל עוד לא עונות: אומרים את זה.
- מדווחים כמה נוצרו, עודכנו ונכשלו, ולכל סוג של כישלון את הסיבה ומה עושים איתו.
מה לא עושים#
- לא מייבאים לאתר בפרודקשן בלי בקשה מפורשת של אדם לאותו אתר.
- לא כותבים לטבלאות התוכן ב-SQL "כדי לתקן" אחרי ייבוא. מתקנים את המיפוי ומריצים עם
restart: true. - לא מוחקים רשומות שיובאו בלי אישור של אדם, גם לא אחרי ייבוא ניסיון.
- קובץ הייצוא מחזיק כתובות דוא"ל של כותבים ותוכן שלא פורסם. בסוף הייבוא מוחקים אותו מהשרת (כפתור "מחיקת הקובץ" בדוח הסיום של האשף), ולא מעתיקים אותו לשום מקום אחר.