פיתוח LMS על 1C-Bitrix: בניית פלטפורמת הדרכה
אתם כבר משתמשים ב-1C-Bitrix עבור החנות או פורטל הארגון שלכם, ועכשיו אתם צריכים להשיק הדרכת שותפים. LMS נפרד פירושו פאנל ניהול נוסף, התחברות נוספת וכאבי ראש בסנכרון. אנחנו פותרים זאת אחרת: אנחנו בונים את הפלטפורמה ישירות בתוך ה-Bitrix שלכם. מאגר משתמשים אחיד, הזמנות משותפות, מודול תשלום—הכל עובד ישירות מהקופסה. ב-10+ שנים יישמנו 7 פרויקטים חינוכיים על Bitrix ואנחנו מכירים את כל המלכודות.
מצב טיפוסי: לקוח כבר מוכר מוצרים דרך חנות מקוונת על Bitrix ועכשיו רוצה להשיק קורסים מקוונים. יישום LMS נפרד (למשל, Moodle) ידרוש שכפול משתמשים, הגדרת SSO והעברת נתונים. כל זה ניתן לפתרון עם כלי Bitrix הסטנדרטיים—אינפובלוקים, HL-בלוקים וקבוצות משתמשים. חיסכון בזמן באינטגרציה—עד 40% בהשוואה לפתרונות חיצוניים.
למה Bitrix מתאים ל-LMS
Bitrix מספק אינפובלוקים לאחסון קורסים ושיעורים, קבוצות משתמשים לגישה, סוכנים למשימות רקע ומערכות תשלום מובנות. LMS מוכן על Bitrix עולה פי 2–3 פחות מיישום Moodle נפרד אם העסק כבר משתמש במערכת האקולוגית של 1C-Bitrix. הכל מנוהל מפאנל ניהול אחד, ולסטודנטים—חשבון אישי מאוחד. בנוסף, אנו משתמשים במטמון מתויג לדפי קורס: כאשר התוכן משתנה, רק המטמון של השיעור הספציפי נמחק, לא כל הסעיף.
ארכיטקטורת אחסון נתונים
ה-LMS על Bitrix בנוי משילוב של אינפובלוקים ו-HighLoad-בלוקים (HL-בלוקים, טבלאות דרך ORM D7).
אינפובלוקים:
| אינפובלוק | קוד | מטרה |
|---|---|---|
| קורסים | lms_courses |
ישויות קורס ראשיות |
| שיעורים | lms_lessons |
שיעורים בתוך קורס |
| מבחנים | lms_quizzes |
מטלות ומבחנים |
HL-בלוקים (דרך ORM):
// Прогресс пользователя class UserProgressTable extends \Bitrix\Main\ORM\Data\DataManager { public static function getTableName(): string { return 'b_hl_lms_user_progress'; } public static function getMap(): array { return [ new IntegerField('ID', ['primary' => true, 'autocomplete' => true]), new IntegerField('USER_ID'), new IntegerField('COURSE_ID'), // ID элемента инфоблока курса new IntegerField('LESSON_ID'), // ID элемента инфоблока урока new EnumField('STATUS', ['values' => ['NOT_STARTED', 'IN_PROGRESS', 'COMPLETED']]), new IntegerField('PROGRESS_PERCENT'), // 0–100 new DatetimeField('STARTED_AT'), new DatetimeField('COMPLETED_AT'), new IntegerField('TIME_SPENT_SEC'), // Время на урок ]; } } // Записи на курс (enrollment) class CourseEnrollmentTable extends \Bitrix\Main\ORM\Data\DataManager { public static function getTableName(): string { return 'b_hl_lms_enrollment'; } public static function getMap(): array { return [ new IntegerField('ID', ['primary' => true, 'autocomplete' => true]), new IntegerField('USER_ID'), new IntegerField('COURSE_ID'), new EnumField('STATUS', ['values' => ['ACTIVE', 'COMPLETED', 'EXPIRED', 'REFUNDED']]), new DatetimeField('ENROLLED_AT'), new DatetimeField('EXPIRES_AT'), // NULL = бессрочно new FloatField('PAID_AMOUNT'), new IntegerField('ORDER_ID'), // Привязка к заказу модуля sale ]; } } מבנה קורס ושיעור
קורס הוא אלמנט אינפובלוק // Прогресс пользователя class UserProgressTable extends \Bitrix\Main\ORM\Data\DataManager { public static function getTableName(): string { return 'b_hl_lms_user_progress'; } public static function getMap(): array { return [ new IntegerField('ID', ['primary' => true, 'autocomplete' => true]), new IntegerField('USER_ID'), new IntegerField('COURSE_ID'), // ID элемента инфоблока курса new IntegerField('LESSON_ID'), // ID элемента инфоблока урока new EnumField('STATUS', ['values' => ['NOT_STARTED', 'IN_PROGRESS', 'COMPLETED']]), new IntegerField('PROGRESS_PERCENT'), // 0–100 new DatetimeField('STARTED_AT'), new DatetimeField('COMPLETED_AT'), new IntegerField('TIME_SPENT_SEC'), // Время на урок ]; } } // Записи на курс (enrollment) class CourseEnrollmentTable extends \Bitrix\Main\ORM\Data\DataManager { public static function getTableName(): string { return 'b_hl_lms_enrollment'; } public static function getMap(): array { return [ new IntegerField('ID', ['primary' => true, 'autocomplete' => true]), new IntegerField('USER_ID'), new IntegerField('COURSE_ID'), new EnumField('STATUS', ['values' => ['ACTIVE', 'COMPLETED', 'EXPIRED', 'REFUNDED']]), new DatetimeField('ENROLLED_AT'), new DatetimeField('EXPIRES_AT'), // NULL = бессрочно new FloatField('PAID_AMOUNT'), new IntegerField('ORDER_ID'), // Привязка к заказу модуля sale ]; } } עם מאפיינים:
| מאפיין | קוד | סוג |
|---|---|---|
| קטגוריה | lms_courses |
רשימה |
| משך | CATEGORY |
מספר |
| רמה | DURATION_HOURS |
רשימה (מתחיל/בינוני/מומחה) |
| סוג גישה | LEVEL |
רשימה (חינם/בתשלום/מנוי) |
| קבוצת גישה | ACCESS_TYPE |
מספר (מזהה קבוצה b_group) |
| תעודה | ACCESS_GROUP_ID |
דגל |
שיעור הוא אלמנט אינפובלוק HAS_CERTIFICATE, מקושר לקורס דרך מאפיין lms_lessons. סדר שיעורים דרך COURSE_ID. סוג תוכן שיעור (SORT): וידאו / טקסט / מבחן / סמינר מקוון.
איך מנוהל גישה לקורס?
הגישה נשלטת דרך קבוצות משתמשים של Bitrix. לכל קורס יש קבוצה משלו (LESSON_TYPE). לאחר תשלום או הרשמה, המשתמש מתווסף לקבוצה:
class EnrollmentService { public function enroll(int $userId, int $courseId): void { $course = \CIBlockElement::GetByID($courseId)->GetNext(); $groupId = (int)$course['PROPERTY_ACCESS_GROUP_ID_VALUE']; if ($groupId) { $currentGroups = \CUser::GetUserGroup($userId); if (!in_array($groupId, $currentGroups)) { $currentGroups[] = $groupId; \CUser::SetUserGroup($userId, $currentGroups); } } CourseEnrollmentTable::add([ 'USER_ID' => $userId, 'COURSE_ID' => $courseId, 'STATUS' => 'ACTIVE', 'ENROLLED_AT' => new \Bitrix\Main\Type\DateTime(), ]); } } הגישה לדפי קורס נבדקת באופן דומה: אם אין רשומת הרשמה או שהסטטוס אינו ACTIVE—הפניה לדף הרכישה.
מעקב התקדמות
ההתקדמות מתועדת במספר תנאים בהתאם לסוג השיעור:
- וידאו: מעקב דרך אירוע נגן
b_group, מסומן כנצפה ב-80% מהווידאו. - טקסט: מסומן כאשר גוללים לסוף (IntersectionObserver על הפסקה האחרונה).
- מבחן: במעבר מוצלח (ציון ≥ סף מעבר).
// AJAX-эндпоинт фиксации прогресса // POST /local/ajax/lms_progress.php $lessonId = (int)$_POST['lesson_id']; $courseId = (int)$_POST['course_id']; $userId = $USER->GetID(); $percent = min(100, (int)$_POST['percent']); $existing = UserProgressTable::getList([ 'filter' => ['USER_ID' => $userId, 'LESSON_ID' => $lessonId], ])->fetch(); if ($existing) { if ($percent > $existing['PROGRESS_PERCENT']) { UserProgressTable::update($existing['ID'], [ 'PROGRESS_PERCENT' => $percent, 'STATUS' => $percent >= 100 ? 'COMPLETED' : 'IN_PROGRESS', 'COMPLETED_AT' => $percent >= 100 ? new \Bitrix\Main\Type\DateTime() : null, ]); } } else { UserProgressTable::add([ 'USER_ID' => $userId, 'COURSE_ID' => $courseId, 'LESSON_ID' => $lessonId, 'STATUS' => $percent >= 100 ? 'COMPLETED' : 'IN_PROGRESS', 'PROGRESS_PERCENT' => $percent, 'STARTED_AT' => new \Bitrix\Main\Type\DateTime(), 'COMPLETED_AT' => $percent >= 100 ? new \Bitrix\Main\Type\DateTime() : null, ]); } בדיקות ומבחנים
שאלות מבחן הן אלמנטים של אינפובלוק class EnrollmentService { public function enroll(int $userId, int $courseId): void { $course = \CIBlockElement::GetByID($courseId)->GetNext(); $groupId = (int)$course['PROPERTY_ACCESS_GROUP_ID_VALUE']; if ($groupId) { $currentGroups = \CUser::GetUserGroup($userId); if (!in_array($groupId, $currentGroups)) { $currentGroups[] = $groupId; \CUser::SetUserGroup($userId, $currentGroups); } } CourseEnrollmentTable::add([ 'USER_ID' => $userId, 'COURSE_ID' => $courseId, 'STATUS' => 'ACTIVE', 'ENROLLED_AT' => new \Bitrix\Main\Type\DateTime(), ]); } } עם מאפיינים: סוג שאלה (בחירה יחידה, בחירה מרובה, תשובה טקסטואלית), אפשרויות תשובה (JSON במאפיין מחרוזת), תשובה נכונה, משקל שאלה.
תוצאות מבחן—HL-בלוק CourseEnrollmentTable:
CREATE TABLE b_hl_lms_quiz_attempt ( ID SERIAL PRIMARY KEY, USER_ID INTEGER, QUIZ_ID INTEGER, SCORE INTEGER, -- набранные баллы MAX_SCORE INTEGER, -- максимум PASSED BOOLEAN, ANSWERS_JSON TEXT, -- JSON с ответами пользователя CREATED_AT TIMESTAMP ); תעודות
בסיום קורס (כל השיעורים COMPLETED)—יצירת תעודת PDF באמצעות ספריית timeupdate או // AJAX-эндпоинт фиксации прогресса // POST /local/ajax/lms_progress.php $lessonId = (int)$_POST['lesson_id']; $courseId = (int)$_POST['course_id']; $userId = $USER->GetID(); $percent = min(100, (int)$_POST['percent']); $existing = UserProgressTable::getList([ 'filter' => ['USER_ID' => $userId, 'LESSON_ID' => $lessonId], ])->fetch(); if ($existing) { if ($percent > $existing['PROGRESS_PERCENT']) { UserProgressTable::update($existing['ID'], [ 'PROGRESS_PERCENT' => $percent, 'STATUS' => $percent >= 100 ? 'COMPLETED' : 'IN_PROGRESS', 'COMPLETED_AT' => $percent >= 100 ? new \Bitrix\Main\Type\DateTime() : null, ]); } } else { UserProgressTable::add([ 'USER_ID' => $userId, 'COURSE_ID' => $courseId, 'LESSON_ID' => $lessonId, 'STATUS' => $percent >= 100 ? 'COMPLETED' : 'IN_PROGRESS', 'PROGRESS_PERCENT' => $percent, 'STARTED_AT' => new \Bitrix\Main\Type\DateTime(), 'COMPLETED_AT' => $percent >= 100 ? new \Bitrix\Main\Type\DateTime() : null, ]); } :
class CertificateGenerator { public function generate(int $userId, int $courseId): string { $user = \CUser::GetByID($userId)->Fetch(); $course = \CIBlockElement::GetByID($courseId)->GetNext(); $pdf = new \TCPDF(); $pdf->AddPage('L'); // Landscape $pdf->setImageScale(1.25); // Фоновое изображение сертификата $pdf->Image('/local/templates/lms/img/certificate_bg.jpg', 0, 0, 297, 210); // ФИО $pdf->SetFont('dejavusans', 'B', 32); $pdf->SetXY(50, 90); $pdf->Cell(200, 20, $user['LAST_NAME'] . ' ' . $user['NAME'], 0, 0, 'C'); // Название курса $pdf->SetFont('dejavusans', '', 18); $pdf->SetXY(50, 120); $pdf->Cell(200, 10, $course['NAME'], 0, 0, 'C'); $filename = 'certificate_' . $userId . '_' . $courseId . '.pdf'; $path = '/upload/certificates/' . $filename; $pdf->Output($_SERVER['DOCUMENT_ROOT'] . $path, 'F'); return $path; } } תהליך העבודה
- אנליטיקה ועיצוב — סיכום על מבנה הקורס, סוגי תוכן, סכמת גישה.
- פיתוח רכיבים — יצירת רכיבי 2.0 לרשימת קורסים, דף פרטים, התקדמות.
- אינטגרציה — חיבור מערכות תשלום (YooKassa, Sber) והחלפה עם 1C דרך CommerceML.
- בדיקות — אימות תרחישים של רכישה, הרשמה, השלמת שיעור ויצירת תעודה.
- פריסה והדרכה — פריסה לשרת ייצור, הדרכת מנהלים (2–3 שעות).
מה כלול בעבודה
בהזמנת פיתוח LMS במפתח מלא, אנו מספקים:
- אנליטיקה ועיצוב סכמת נתונים (אינפובלוקים, HL-בלוקים);
- פיתוח רכיבי 2.0 (רשימת קורסים, פרטים, התקדמות);
- אינטגרציה עם מערכות תשלום ו-1C;
- בדיקות ותיקון באגים;
- מסירת קוד מקור, תיעוד וגישות;
- הדרכת מנהלים.
לוח זמנים לפיתוח
| וריאנט | היקף | משך |
|---|---|---|
| LMS בסיסי | קורסים, שיעורים, התקדמות, גישה קבוצתית | 15–20 ימים |
| עם מבחנים ותעודות | + מבחנים, יצירת PDF | 20–30 ימים |
| פלטפורמה מלאה | + תשלומים, מנויים, אנליטיקה, סמינרים מקוונים | 35–50 ימים |
רוצים לדון בפרויקט שלכם? צרו קשר—נעריך את המשימה שלכם ונציע פתרון אופטימלי. הזמינו פיתוח LMS—וקבלו פתרון מוכן בתוך לוחות זמנים מוסכמים.







