> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# أدوات SCORM من التأليف Authoring إلى التشغيل في منصتك
- URL: https://arabroot.io/articles/ادوات-scorm-من-التاليف-الى-التشغيل/
- Published: 2026-10-14T11:45:00.000Z
- Updated: 2026-10-25T08:50:23.000Z
- Description: أدوات تأليف SCORM التجارية والمفتوحة بأسعارها، وكيف تختبر الحزمة، ثم دورة من eXeLearning تعمل في Moodle وفي صفحتك أنت.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, التعليم والبحث العلمي, تطبيقات لفريقك, الاستضافة الذاتية, SCORM

في مقال [ما هو SCORM](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-scorm-%D9%88%D9%83%D9%8A%D9%81-%D9%8A%D8%AA%D9%88%D8%A7%D8%B5%D9%84-%D8%A7%D9%84%D9%85%D8%AD%D8%AA%D9%88%D9%89-%D9%85%D8%B9-lms/) كتبنا حزمة بأيدينا، ملف وصف `imsmanifest.xml` وصفحتي HTML ودالة تبحث عن ال API، وهذا مفيد لتفهم ما يحدث، ولكن لا أحد يبني دورة من عشرين درساً بهذه الطريقة. ففي الواقع يبني المصمم التعليمي الدورة في أداة تأليف Authoring Tool، ويصدرها حزمة SCORM، ثم يأتي سؤالان لا يقلان أهمية: كيف تتأكد أن الحزمة سليمة قبل أن تصل إلى ألف طالب؟ وإذا كانت عندك منصة خاصة بك وليست LMS جاهزاً، فكيف تشغل فيها حزمة SCORM؟

المواضيع في السلسلة:

- [ما هو SCORM؟ الإصدارات وكيف يتواصل المحتوى مع LMS](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-scorm-%D9%88%D9%83%D9%8A%D9%81-%D9%8A%D8%AA%D9%88%D8%A7%D8%B5%D9%84-%D8%A7%D9%84%D9%85%D8%AD%D8%AA%D9%88%D9%89-%D9%85%D8%B9-lms/).
- أدوات SCORM من التأليف Authoring إلى التشغيل في منصتك (الموضوع الحالي).
- [تتبع تقدم المتعلم Learner Tracking من SCORM إلى xAPI](https://arabroot.io/articles/%D9%85%D8%B9%D8%A7%D9%8A%D9%8A%D8%B1-%D9%85%D8%AD%D8%AA%D9%88%D9%89-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-scorm-%D8%A7%D9%85-xapi-%D8%A7%D9%85-cmi5/).

في هذا المقال سوف نتناول:

- أين تقع كل أداة في الطريق من التأليف إلى الاختبار إلى التشغيل.
- أدوات التأليف التجارية بأسعارها من صفحاتها الرسمية في 22 أكتوبر 2026، والأدوات مفتوحة المصدر، وأين يقف H5P.
- مختبر: دورة صغيرة بنيناها في eXeLearning على Docker، وصدرناها SCORM 1.2، وشغلناها في Moodle 5.3، مع ما وجدناه من إعدادات تمنع وصول الدرجة.
- اختبار الحزمة قبل الرفع: SCORM Cloud وأسعاره، وما يقوله Moodle عن اختبارات المطابقة.
- تشغيل الحزمة نفسها في صفحة ويب عادية بمكتبة scorm-again، وما يرسله المتصفح إلى الخادم الخلفي Backend.
- دعم SCORM في Moodle وOpen edX وCanvas وChamilo، وجدول يساعدك على الاختيار.

## أين تقع كل أداة؟

قبل أن ندخل في الأسماء والأسعار، الصورة التالية تبين المراحل الثلاث، وكل أداة في المقال تقع في واحدة منها:

![مخطط من ثلاث مراحل: 1 التأليف Authoring بأدوات تجارية باشتراك سنوي هي Articulate Storyline وRise وAdobe Captivate وiSpring Suite تعمل على جهاز المصمم أو في السحابة، وأدوات مفتوحة المصدر هي eXeLearning برخصة AGPL-3.0 وAdapt برخصة GPL-3.0 تثبتها على سيرفرك أو جهازك، والمخرج ملف Zip فيه imsmanifest.xml بإصدار SCORM 1.2 أو 2004 تختاره عند التصدير، ثم 2 الاختبار Testing بحزمة course.zip ترفعها إلى SCORM Cloud من Rustici لتشغلها وتقرأ سجل الاستدعاءات قبل أن تصل إلى ال LMS، أو LMS تجريبي عندك مثل Moodle، ثم 3 التشغيل Runtime في LMS فيه مشغل جاهز مثل Moodle وChamilo بإصدار SCORM 1.2 وOpen edX مع SCORM XBlock وCanvas مع External Tool، أو منصتك أنت بمكتبة scorm-again برخصة MIT تضع window.API في صفحتك وترسل القيم إلى الخادم الخلفي، ومكتبة pipwerks داخل الحزمة نفسها تبحث عن ال API](https://arabroot.io/content/images/2026/10/scorm-tools-01-chain.webp)

التأليف ينتج الحزمة، والاختبار يكشف أخطاءها، والمشغل يحدد أي إصدار يعمل

ولاحظ أن مكتبتي pipwerks وscorm-again في المرحلة نفسها ولكن في جهتين مختلفتين، فالأولى داخل الحزمة وتمثل المحتوى، والثانية في صفحة المنصة وتمثل ال LMS، وسوف نراهما معاً في المختبر.

## أدوات التأليف Authoring Tools

كل أداة تأليف جادة تصدر SCORM، فالسؤال ليس هل تدعمه، وإنما بأي إصدار، وكم تكلف، وأين تعمل، ومن يستطيع استخدامها في فريقك. والأسعار التالية من الصفحات الرسمية كما قرأناها في 22 أكتوبر 2026، وهي بالدولار الأمريكي قبل الضرائب، وتتغير كثيراً، فراجعها قبل الشراء.

| الأداة                                                  | الترخيص والسعر                                                                                                                                                              | الصيغ التي تصدرها                                                                                                                                                                            | أين تعمل                                                      |
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| Articulate 360 AI (Storyline وRise)                     | اشتراك 1,749 دولاراً للمقعد سنوياً للفرق، و1,449 للأفراد بحسب [صفحة الأسعار](https://www.articulate.com/360/pricing/?ref=arabroot.io)                                       | SCORM 1.2 حتى SCORM 2004 الإصدار الرابع، وxAPI، وcmi5 في Storyline 360 بحسب [صفحة الدعم](https://www.articulatesupport.com/article/articulate-storyline-is-scorm-conformant?ref=arabroot.io) | Storyline برنامج سطح مكتب، وRise في المتصفح                   |
| Adobe Captivate                                         | 39.99 دولاراً شهرياً للفرد بحسب [دليل الشراء](https://www.adobe.com/products/captivate/buying-guide.html?ref=arabroot.io)، والفرق والتعليم بعرض سعر                         | SCORM 1.2 وSCORM 2004 وAICC وxAPI بحسب [صفحة النشر](https://helpx.adobe.com/captivate/help/publish-projects-adobe-captivate.html?ref=arabroot.io)                                            | برنامج سطح مكتب                                               |
| iSpring Suite                                           | 970 دولاراً للمؤلف سنوياً، وiSpring Suite AI بـ 1,290، وiSpring Cloud AI بـ 720 بحسب [صفحة الأسعار](https://www.ispringsolutions.com/ispring-suite/pricing?ref=arabroot.io) | SCORM 1.2 وSCORM 2004 وxAPI وcmi5 بحسب [صفحة المنتج](https://www.ispringsolutions.com/ispring-suite?ref=arabroot.io)                                                                         | يعمل مع PowerPoint، ومنه نسخة سحابية                          |
| Elucidat                                                | أصبحت منتجاً اسمه Create داخل منصة أكبر، والسعر بعرض سعر بحسب [صفحة الأسعار](https://www.elucidat.com/pricing/?ref=arabroot.io)                                             | لم نجد صفحة رسمية حديثة تحدد الإصدارات                                                                                                                                                       | سحابية                                                        |
| [eXeLearning](https://exelearning.net/?ref=arabroot.io) | مفتوح المصدر برخصة AGPL-3.0، مجاني                                                                                                                                          | SCORM 1.2 وSCORM 2004 وIMS CP وموقع HTML وePub3، وجربناه في المختبر                                                                                                                          | Docker على سيرفرك، أو برنامج سطح مكتب                         |
| [Adapt](https://www.adaptlearning.org/?ref=arabroot.io) | مفتوح المصدر برخصة GPL-3.0، مجاني                                                                                                                                           | SCORM 1.2 افتراضياً وSCORM 2004 الإصدار الرابع بإضافة [spoor](https://github.com/adaptlearning/adapt-contrib-spoor?ref=arabroot.io)                                                          | إطار عمل Framework، وأداة تأليف على الويب بـ Node.js وMongoDB |

وفيما يلي كل أداة بنقاط قوتها وضعفها من منظور من يدير المنصة، وليس من منظور المصمم وحده:

- **Articulate 360 AI:** نقاط القوة أن Storyline هو ما يعرفه أغلب المصممين التعليميين، وأنه يغطي كل الصيغ حتى cmi5، وأن Rise يبني دورات تتكيف مع الجوال بسرعة. ونقاط الضعف السعر لكل مقعد، و[صفحة الدعم](https://www.articulatesupport.com/article/articulate-storyline-is-scorm-conformant?ref=arabroot.io) نفسها تقول إن Articulate لم تقدم Storyline لشهادة مطابقة مستقلة.
- **Adobe Captivate:** نقاط القوة أن له سعراً شهرياً معلناً للفرد، فيناسب مصمماً واحداً في مشروع محدد. ونقاط الضعف أن السعر الشهري يتراكم إذا استمر العمل، وأن صفحات المساعدة من Adobe رفضت أدوات الفحص عندنا يوم الكتابة فلم نقرأ قائمة الصيغ منها مباشرة، فتأكد من خيارات النشر في نسختك.
- **iSpring Suite:** نقاط القوة أنه يحول عروض PowerPoint الموجودة عند المعلمين إلى دورات، وهذا يختصر الطريق في مؤسسة تعليمية فيها مئات العروض. ونقاط الضعف أنه مبني حول PowerPoint، والسعر لكل مؤلف.
- **eXeLearning:** نقاط القوة أنه مجاني ويعمل في Container واحد، ويصدر الصيغتين، ويطوره مشروع تقوده وزارة التعليم الإسبانية بحسب [مستودعه](https://github.com/exelearning/exelearning?ref=arabroot.io). ونقاط الضعف أن قائمة لغات الواجهة في ملف README لا تشمل العربية، وأن إرسال الدرجة يحتاج إعدادين لا يظهران للمستخدم الجديد كما سيأتي.
- **Adapt:** نقاط القوة أن الدورات تتكيف مع الشاشات، وأن إضافة spoor تتيح ضبطاً دقيقاً لما يرسل إلى ال LMS، مثل التفاعلات `cmi.interactions` وحالة الخروج. ونقاط الضعف أن أداة التأليف على الويب آخر إصدار لها 0.11.5 في يناير 2025 بحسب [مستودعها](https://github.com/adaptlearning/adapt%5Fauthoring?ref=arabroot.io)، وتحتاج Node.js وMongoDB، وهي أثقل في التشغيل من eXeLearning، لذلك لم نختبرها في هذا المقال.

💡

وأين H5P؟ H5P صيغة مستقلة وليست SCORM، والدرجة فيه تصل بعبارات xAPI كما رأينا في [مقال H5P](https://arabroot.io/articles/%D9%85%D8%AD%D8%AA%D9%88%D9%89-%D8%AA%D9%81%D8%A7%D8%B9%D9%84%D9%8A-%D9%82%D8%A7%D8%A8%D9%84-%D9%84%D8%A7%D8%B9%D8%A7%D8%AF%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D8%B9-h5p/)، فإذا كانت منصتك تقبل H5P مثل Moodle فارفعه كما هو، وإذا كانت لا تقبل إلا SCORM فأنت تحتاج أداة تحول المحتوى إلى حزمة SCORM، ولم نختبر هذا التحويل.

## التجربة العملية: دورة من eXeLearning إلى Moodle

اخترنا eXeLearning لأنه يعمل في Container واحد بقاعدة SQLite داخلية، والإصدار 4.0.5 صدر في 16 سبتمبر 2026 بحسب [صفحة الإصدار](https://github.com/exelearning/exelearning/releases/tag/v4.0.5?ref=arabroot.io)، والأمر من ملف README في المستودع مع تثبيت الإصدار وحد للذاكرة:

```bash
docker run -d --name edu6-exe -p 127.0.0.1:32180:8080 --memory 768m exelearning/exelearning:v4.0.5
docker logs edu6-exe 2>&1 | tail -4
```

```text
Elysia server running at http://localhost:8080
Pages: /login, /workarea
Auth endpoints: /api/auth/login, /api/auth/logout, /api/session/check
Project endpoints: /api/project/*, /api/export/*
```

ملف README يذكر حساباً افتراضياً، ولكن الدخول به في هذه ال Image رجع بالرسالة «Invalid credentials»، فأنشأنا حساباً بأداة سطر الأوامر في ال Container:

```bash
docker exec edu6-exe bun run dist/cli.js create-user teacher@example.com 'change-me-teacher' teacher1
```

```text
SUCCESS User teacher@example.com created successfully (id: 1)
```

### بناء الدورة في المحرر

دخلنا إلى المحرر، وكتبنا عنوان المشروع «أساسيات DNS» في خصائص المشروع Project Properties، ثم أضفنا إلى الصفحة الأولى نشاط «صح أو خطأ» True or false من فئة Assessment and tracking، وكتبنا فيه السؤال «السجل MX يربط اسم النطاق بعنوان IPv4» والإجابة الصحيحة «خطأ»، وترجمنا نصوص الأزرار في تبويب Custom texts إلى «صح» و«خطأ» و«تحقق». وهنا أول ما يجب أن تعرفه: في تبويب SCORM للنشاط ثلاثة خيارات، والافتراضي منها «Do not save the score»، أي أن النشاط لا يرسل أي درجة إلى ال LMS ما لم تغيره:

![محرر eXeLearning 4.0.5 بعنوان المشروع أساسيات DNS: نشاط True or false مفتوح للتحرير على تبويب SCORM، وفيه ثلاثة خيارات Do not save the score وAutomatically save the score وهو المختار وShow a button to save the score، وتحتها ملاحظتان This will only work when exported as SCORM وThe score will be automatically saved after answering each question and at the end of the game، وحقل Weighted بقيمة 100%](https://arabroot.io/content/images/2026/10/scorm-tools-02-exe-scorm-tab.webp)

تبويب SCORM في نشاط eXeLearning: الافتراضي ألا ترسل الدرجة، واخترنا الحفظ التلقائي

اخترنا «Automatically save the score» وضغطنا حفظ النشاط، فرفض المحرر الحفظ برسالة «SCORM grades can only be saved in Quiz mode»، أي أن الدرجة لا ترسل إلا إذا فعلت وضع الاختبار من خيارات النشاط في تبويب General settings، ففعلناه وحفظنا. وهذا الإعداد المزدوج هو أكثر سبب سوف تسمعه من المعلمين: «الطالب حل الاختبار والدرجة لا تظهر». والصورة التالية للنشاط بعد الحفظ:

![محرر eXeLearning بعد حفظ النشاط: صفحة New page فيها نشاط True or false بنص Answer all the questions in this quiz، والسؤال السجل MX يربط اسم النطاق بعنوان IPv4 بترتيب كلمات مختلط من اليسار إلى اليمين، وخياران صح وخطأ وزر تحقق، وفي الأسفل رسالة The score can't be saved because this page is not part of a SCORM package](https://arabroot.io/content/images/2026/10/scorm-tools-03-exe-editor.webp)

النشاط في المحرر: السؤال العربي يعرض من اليسار إلى اليمين، والرسالة السفلية تذكر أن الدرجة تحفظ داخل حزمة SCORM فقط

لاحظ ترتيب الكلمات في السؤال، فالمحتوى يعرض من اليسار إلى اليمين، ولاحظ أن الحزمة التي صدرناها كان في صفحتها الرئيسية `<html lang="en">`، أي أن لغة المشروع بقيت الإنجليزية، فاضبط اللغة في خصائص المشروع قبل التصدير، وافتح الحزمة على منصتك لتتأكد من اتجاه النص.

### التصدير بصيغة SCORM 1.2 وSCORM 2004

من قائمة File ثم Download as تجد SCORM 1.2، ولكن في كود الواجهة للإصدار 4.0.5 عنصر SCORM 2004 مخفي بالصنف `d-none`، بينما أداة سطر الأوامر و[ملف التصدير](https://github.com/exelearning/exelearning/blob/v4.0.5/src/cli/commands/elp-export.ts?ref=arabroot.io) فيهما الصيغتان. فصدرنا الحزمتين من واجهة REST التي يطبعها السيرفر عند التشغيل، برقم المشروع من رابط المحرر:

```bash
TOKEN=$(curl -s -X POST -H 'Content-Type: application/json' \
  -d '{"email":"teacher@example.com","password":"change-me-teacher"}' \
  http://127.0.0.1:32180/api/auth/login | sed 's/.*"access_token":"\([^"]*\)".*/\1/')
P=24fff377-1f1d-4d05-a5bf-bf3b6b4bb44d
for f in scorm12 scorm2004; do
  curl -s -H "Authorization: Bearer $TOKEN" -o dns-$f.zip -w "$f %{http_code} %{size_download}\n" \
    http://127.0.0.1:32180/api/v1/export/projects/$P/export/$f
done
```

```text
scorm12 200 312872
scorm2004 200 277860
```

وفي الحزمة الأولى 90 ملفاً، وهذا أول ملف الوصف منها:

```xml
<manifest identifier="eXe-MANIFEST-20261022020205W9R1XA"
  xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"
  xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2"
  xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2">
  <metadata>
    <schema>ADL SCORM</schema>
    <schemaversion>1.2</schemaversion>
    <adlcp:location>imslrm.xml</adlcp:location>
  </metadata>
  <organizations default="eXe-20261022020205W9R1XA">
    <organization identifier="eXe-20261022020205W9R1XA" structure="hierarchical">
      <title>أساسيات DNS</title>
      <item identifier="ITEM-ROOT-20261022020205W9R1XA" isvisible="true">
        <title>أساسيات DNS</title>
        <item identifier="ITEM-0a4e7af5-ecd0-486c-8707-81b9a7f27158" identifierref="RES-0a4e7af5-ecd0-486c-8707-81b9a7f27158" isvisible="true">
          <title>New page</title>
        </item>
      </item>
    </organization>
  </organizations>
  <resources>
    <resource identifier="RES-0a4e7af5-ecd0-486c-8707-81b9a7f27158" type="webcontent" adlcp:scormtype="sco" href="index.html">
      <file href="index.html"/>
      <dependency identifierref="COMMON_FILES"/>
    </resource>
    <resource identifier="COMMON_FILES" type="webcontent" adlcp:scormtype="asset">
      <file href="content.dtd"/>
      <file href="content.xml"/>
      <file href="libs/SCOFunctions.js"/>
      <file href="libs/SCORM_API_wrapper.js"/>
      <!-- 80 more files: theme, bootstrap, jquery, idevices/trueorfalse -->
    </resource>
  </resources>
</manifest>
```

في الملف أعلاه لاحظ التالي:

- البنية نفسها التي كتبناها بأيدينا في المقال السابق: فهرس فيه عنصر لكل صفحة، ومورد SCO لكل صفحة، ومورد Asset للملفات المشتركة يعتمد عليه الباقي.
- الحزمة تحمل الملف `libs/SCORM_API_wrapper.js`، وفي رأسه أنه مكتبة [pipwerks SCORM Wrapper](https://github.com/pipwerks/scorm-api-wrapper?ref=arabroot.io) برخصة على نمط MIT، أي أن eXeLearning لا يكتب دالة البحث عن ال API بنفسه.
- عنوان الصفحة «New page» لأننا لم نغير اسم الصفحة، وهو ما سوف يراه الطالب في قائمة المشغل، فسم الصفحات قبل التصدير.
- حزمة SCORM 2004 فيها `2004 4th Edition` وقاعدة تنقل `imsss:controlMode choice="true" choiceExit="true" flow="true"`.

### تشغيل الحزمة في Moodle

رفعنا حزمة SCORM 1.2 إلى المقرر نفسه في مختبر Moodle 5.3 من [المقال السابق](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-scorm-%D9%88%D9%83%D9%8A%D9%81-%D9%8A%D8%AA%D9%88%D8%A7%D8%B5%D9%84-%D8%A7%D9%84%D9%85%D8%AD%D8%AA%D9%88%D9%89-%D9%85%D8%B9-lms/#lab) بالسكربت التالي:

```php
<?php
// Adds the SCORM 1.2 package exported from eXeLearning to course NET101.
define('CLI_SCRIPT', true);
require('/var/www/html/config.php');
require_once($CFG->libdir . '/testing/generator/lib.php');
require_once($CFG->dirroot . '/mod/scorm/locallib.php');
\core\session\manager::set_user(get_admin());
$gen = new testing_data_generator();
$course = $DB->get_record('course', ['shortname' => 'NET101'], '*', MUST_EXIST);
copy('/tmp/exe-dns-scorm12.zip', $CFG->dirroot . '/lab-exe.zip');
$scorm = $gen->get_plugin_generator('mod_scorm')->create_instance([
    'course' => $course->id, 'name' => 'اختبار من eXeLearning (SCORM 1.2)',
    'packagefilepath' => $CFG->dirroot . '/lab-exe.zip', 'maxgrade' => 100, 'grademethod' => GRADEHIGHEST, 'maxattempt' => 0]);
unlink($CFG->dirroot . '/lab-exe.zip');
echo "scorm={$scorm->id} cmid={$scorm->cmid} version=" . $DB->get_field('scorm', 'version', ['id' => $scorm->id]) . "\n";
```

```text
scorm=4 cmid=4 version=SCORM_1.2
```

ثم فتحنا النشاط بحساب الطالب، ولفننا دوال `window.API` في صفحة المشغل بدالة تسجل كل استدعاء، وذلك بعد أن فتح المشغل الجلسة، لذلك لا يظهر `LMSInitialize` في السجل. وأجاب الطالب «خطأ» وضغط «تحقق»:

```text
LMSGetValue(cmi.core.lesson_status) -> "not attempted"
LMSSetValue(cmi.core.lesson_status, incomplete) -> "true"
LMSGetValue(cmi.student_data.mastery_score) -> ""
LMSGetValue(cmi.suspend_data) -> ""
LMSGetValue(cmi.core.student_name) -> "خالد الطالب"
LMSGetValue(cmi.core.score.raw) -> ""
LMSSetValue(cmi.core.score.max, 100) -> "true"
LMSSetValue(cmi.core.score.min, 0) -> "true"
LMSGetValue(cmi.core.lesson_status) -> "incomplete"
LMSGetValue(cmi.core.score.raw) -> ""
LMSGetValue(cmi.core.lesson_status) -> "incomplete"
LMSGetValue(cmi.core.lesson_status) -> "incomplete"
LMSSetValue(cmi.suspend_data, exe12/1|idevice-1792634479315-h3uu5uwjf;7;0;1;100;100;0;100) -> "true"
LMSSetValue(cmi.core.score.raw, 100) -> "true"
LMSGetValue(cmi.core.lesson_status) -> "incomplete"
LMSSetValue(cmi.core.lesson_status, passed) -> "true"
LMSSetValue(cmi.core.exit, ) -> "true"
LMSCommit() -> "true"
LMSGetValue(cmi.core.lesson_status) -> "passed"
LMSCommit() -> "true"
LMSCommit() -> "true"
```

في المخرج أعلاه لاحظ التالي:

- الحزمة سألت عن `mastery_score` فرجعت فارغة، لأن eXeLearning لا يكتب `masteryscore` في ملف الوصف، فالحزمة نفسها هي التي قررت `passed`.
- الحزمة تحفظ حالتها الداخلية في `suspend_data` بصيغة خاصة بها تبدأ بـ `exe12`، ولا يفهمها ال LMS، ولا يحتاج أن يفهمها، فهو يحفظها ويعيدها فقط.
- الحزمة استدعت `LMSCommit` ثلاث مرات ولم تستدع `LMSFinish` طوال الجلسة، أي أنها تعتمد على الحفظ بعد كل خطوة، وهذا ما ينقذها إذا أغلق الطالب الصفحة.

![حزمة eXeLearning داخل مشغل Moodle بالعربية: عنوان النشاط اختبار من eXeLearning (SCORM 1.2)، والقائمة الجانبية أساسيات DNS وتحتها New page بعلامة صح، والمحتوى أساسيات DNS وNew page وشارة Your score: 100/100، ونشاط True or false بالسؤال والإجابة خطأ مختارة ورسالة Correct](https://arabroot.io/content/images/2026/10/scorm-tools-05-exe-answered.webp)

الحزمة نفسها داخل Moodle: الدرجة 100/100 والصفحة مكتملة في القائمة

وفي قاعدة البيانات حفظ Moodle الحالة `passed` والدرجة 100 وبيانات الاستئناف، أي أن الطريق من أداة التأليف إلى سجل الدرجات يعمل، بشرط الإعدادين اللذين ذكرناهما.

## اختبار الحزمة قبل الرفع

الطريقة البسيطة أن ترفع الحزمة إلى المنصة الحقيقية وتنتظر شكاوى الطلاب، وهي أسوأ الطرق على الإطلاق، لأن المحاولات الخاطئة تبقى في سجل الدرجات، ولأن بعض الأخطاء لا تظهر لأحد، مثل الإطار الفارغ الذي رأيناه في المقال السابق. والطرق الأفضل ثلاث:

- **SCORM Cloud من Rustici:** خدمة سحابية ترفع إليها الحزمة وتشغلها وتقرأ سجل الاستدعاءات، وتدعم SCORM وxAPI وcmi5 وAICC بحسب [صفحة الأسعار](https://rusticisoftware.com/products/scorm-cloud/pricing/?ref=arabroot.io)، والاختبار نفسه غير محدود في كل الخطط.
- **LMS تجريبي عندك:** نسخة من منصتك نفسها بالإصدار نفسه، مثل مختبر Moodle في المقال السابق، لأن الحزمة التي تعمل في SCORM Cloud قد تتصرف بشكل مختلف في منصتك، كما رأينا مع حد `suspend_data` في Moodle.
- **اختبارات المطابقة من ADL:** [سؤال وجواب SCORM في Moodle](https://docs.moodle.org/503/en/SCORM%5FFAQ?ref=arabroot.io) يذكر أن Moodle يجتاز اختبارات ADL Conformance Test Suite بالإصدار 1.2.7 لـ SCORM 1.2، وهذه الاختبارات تخص من يطور LMS أو أداة تأليف، ولم نتمكن من فتح موقع ADL من شبكتنا يوم الكتابة.

وهذه خطط SCORM Cloud كما في صفحته في 22 أكتوبر 2026، والتسجيل Registration يعني ربط متعلم بمقرر مرة واحدة، ثم يفتحه المتعلم كما يشاء دون تسجيل جديد:

| الخطة  | السعر شهرياً | التسجيلات                                | تكلفة التسجيل الإضافي |
| ------ | ------------ | ---------------------------------------- | --------------------- |
| Trial  | مجانية       | 10 قابلة لإعادة الضبط، و3 مقررات حتى 5GB | لا يوجد               |
| Tester | 40 دولاراً   | 10 قابلة لإعادة الضبط                    | لا يوجد               |
| Little | 90 دولاراً   | 50 شهرياً                                | 3.60 دولار            |
| Medium | 180 دولاراً  | 100 شهرياً                               | 3.60 دولار            |
| Big    | 360 دولاراً  | 300 شهرياً                               | 0.40 دولار            |

وللخطط الأكبر حتى 50,000 تسجيل شهرياً أسعار في الصفحة نفسها، ولكن لاحظ أن هذه الخطط لتشغيل المقررات للمتعلمين، وأما اختبار الحزم فالخطة المجانية تكفيه في أغلب الحالات.

## تشغيل SCORM في منصتك أنت

لنفرض أن مؤسستك بنت منصة تدريب خاصة بها، وطلب منك أن تشغل فيها حزم SCORM التي اشترتها. والطريقة البسيطة أن تكتب كائن `window.API` بنفسك بالدوال الثماني، وهذا يعمل مع حزمتك الأولى، ثم تأتي حزمة تكتب قيمة بصيغة غير متوقعة، أو تقرأ عنصراً لم تبرمجه، فتتصرف حزمة تجارية بشكل لا تفهمه. والحل الأنسب أن تأخذ مكتبة تطبق نموذج البيانات كاملاً وتتحقق من القيم، وتكتب أنت التخزين فقط. والصورة التالية تبين ما تكتبه وما تأخذه جاهزاً:

![مخطط تشغيل حزمة SCORM في منصتك: في متصفح المتعلم صفحتك index.html فيها scorm-again في صفحتك window.API = new Scorm12API مع lmsCommitUrl /commit يتحقق من الأسماء والقيم ويعيد رموز الأخطاء مثل 405، وما تكتبه أنت loadFromJSON بهوية المتعلم والتقدم المحفوظ قبل فتح الحزمة، وiframe فيه course/index.html الحزمة كما صدرتها أداة التأليف وفيها SCORM_API_wrapper.js من pipwerks يبحث عن window.API، ثم 1 LMSInitialize و2 LMSSetValue للدرجة 100 و3 LMSCommit، ولا تعدل في الحزمة شيئاً، وسهم من scorm-again إلى الخادم الخلفي Backend الذي يستقبل POST /commit بكائن cmi كامل فيه lesson_status passed والدرجة 100، الكائن كاملاً في كل مرة وليس الفرق فقط، وما تكتبه أنت في الخادم: تحفظ الكائن لكل متعلم ومقرر وتعيده عند الفتح التالي وتحول الدرجة إلى سجل الدرجات](https://arabroot.io/content/images/2026/10/scorm-tools-04-own-player.webp)

المكتبة تكفيك جانب المتصفح، والتخزين والهوية والدرجات عمل منصتك

والمكتبة التي جربناها [scorm-again](https://github.com/jcputney/scorm-again?ref=arabroot.io)، برخصة MIT، وتدعم SCORM 1.2 وSCORM 2004 وتطبق ال API في المتصفح، وأحدث إصدار منها 3.4.7\. حملنا الحزمة من npm وأخذنا منها الملف `dist/scorm12.min.js` إلى مجلد `public/lib`، وفردنا حزمة eXeLearning في `public/course`، ثم كتبنا الصفحة التالية:

```bash
npm pack scorm-again@3.4.7
tar xzf scorm-again-3.4.7.tgz
mkdir -p public/lib public/course
cp package/dist/scorm12.min.js public/lib/
unzip -q dns-scorm12.zip -d public/course
```

```html
<!doctype html>
<html lang="ar" dir="rtl">
<head>
  <meta charset="utf-8">
  <title>مشغل SCORM بسيط</title>
  <style>
    body { font-family: "Segoe UI", Tahoma, sans-serif; margin: 0; display: grid; grid-template-columns: 1fr 520px; height: 100vh; }
    iframe { width: 100%; height: 100%; border: 0; border-left: 1px solid #ddd; }
    #log { direction: ltr; margin: 0; padding: 12px; background: #17111A; color: #9EE6B8; font: 12px/1.6 Consolas, monospace; overflow: auto; white-space: pre-wrap; }
  </style>
  <script src="lib/scorm12.min.js"></script>
</head>
<body>
  <iframe id="sco" title="المحتوى"></iframe>
  <pre id="log"></pre>
  <script>
    const log = (line) => { document.getElementById('log').textContent += line + '\n'; };
    // The runtime the SCO will find in window.parent: scorm-again plays the LMS role in the browser
    window.API = new Scorm12API({
      lmsCommitUrl: '/commit',
      dataCommitFormat: 'json',
      autocommit: false,
      logLevel: 4
    });
    // Data the LMS gives the learner before launch (normally from your database)
    window.API.loadFromJSON({ core: { student_id: 'student1', student_name: 'Khalid' } });
    window.API.on('LMSInitialize', () => log('LMSInitialize()'));
    window.API.on('LMSSetValue.cmi.*', (element, value) => log('LMSSetValue(' + element + ', ' + value + ')'));
    window.API.on('LMSCommit', () => log('LMSCommit()'));
    window.API.on('LMSFinish', () => log('LMSFinish()'));
    window.API.on('CommitSuccess', () => log('-> POST /commit OK'));
    document.getElementById('sco').src = 'course/index.html';
  </script>
</body>
</html>
```

ولكي نرى ما يصل إلى الخادم الخلفي كتبنا سيرفراً صغيراً بـ Node.js دون أي مكتبة، يعرض الملفات ويطبع كل طلب على `/commit`، وهو مكان قاعدة بياناتك في المنصة الحقيقية:

```javascript
// A tiny "LMS" for the lab: serves the player page and the SCORM package, and prints each commit it receives.
import { createServer } from 'node:http';
import { readFile } from 'node:fs/promises';
import { extname, join, normalize } from 'node:path';

const ROOT = '/app/public';
const TYPES = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript', '.css': 'text/css', '.xml': 'application/xml',
  '.png': 'image/png', '.svg': 'image/svg+xml', '.gif': 'image/gif', '.ico': 'image/x-icon', '.json': 'application/json' };

createServer(async (req, res) => {
  if (req.method === 'POST' && req.url === '/commit') {
    let body = '';
    for await (const chunk of req) body += chunk;
    console.log(new Date().toISOString(), 'COMMIT', body);
    res.writeHead(200, { 'Content-Type': 'application/json' });
    return res.end(JSON.stringify({ result: true, errorCode: 0 }));
  }
  const path = normalize(decodeURIComponent(new URL(req.url, 'http://x').pathname)).replace(/^(\.\.[/\\])+/, '');
  try {
    const file = path.endsWith('/') ? path + 'index.html' : path;
    const data = await readFile(join(ROOT, file));
    res.writeHead(200, { 'Content-Type': TYPES[extname(file)] || 'application/octet-stream' });
    res.end(data);
  } catch {
    res.writeHead(404); res.end('not found');
  }
}).listen(8080, () => console.log('listening on 8080'));
```

```bash
docker run -d --name edu6-scorm-player --memory 128m -p 127.0.0.1:32190:8080 \
  -v "$PWD":/app:ro node:24-alpine node /app/server.mjs
```

وفي أول تشغيل حمل المتصفح الصفحة الرئيسية كملف بدل أن يعرضها، والسبب أن السيرفر حدد نوع المحتوى من امتداد المسار `/` وهو فارغ، فأرسل `application/octet-stream`، فإذا كتبت سيرفراً لملفات الحزم فحدد النوع من اسم الملف الذي قرأته فعلاً كما في السطر `const file` أعلاه. ثم فتحنا الصفحة وأجبنا عن السؤال:

![صفحة ويب عادية على يسارها سجل أسود بالاستدعاءات LMSInitialize ثم LMSSetValue للحالة incomplete والدرجة القصوى 100 والدنيا 0 وsuspend_data والدرجة 100 والحالة passed وcmi.core.exit فارغة ثم LMSCommit ثلاث مرات، وعلى يمينها حزمة eXeLearning أساسيات DNS وYour score: 100/100 ونشاط True or false بالإجابة خطأ ورسالة Correct](https://arabroot.io/content/images/2026/10/scorm-tools-06-scorm-again.webp)

الحزمة نفسها التي عملت في Moodle تعمل في صفحة عادية، والسجل على اليسار من أحداث scorm-again

وهذا ما طبعه السيرفر عند أول `LMSCommit`:

```text
2026-10-22T02:11:15.000Z COMMIT {"cmi":{"suspend_data":"exe12/1|idevice-1792634479315-h3uu5uwjf;7;0;1;100;100;0;100","launch_data":"","comments":"","comments_from_lms":"","core":{"student_id":"student1","student_name":"Khalid","lesson_location":"","credit":"","lesson_status":"passed","entry":"","lesson_mode":"normal","exit":"","session_time":"00:00:00","score":{"raw":"100","min":"0","max":"100"}},"objectives":{},"student_data":{"mastery_score":"","max_time_allowed":"","time_limit_action":""},"student_preference":{"audio":"","language":"","speed":"","text":""},"interactions":{}}}
```

في المخرج أعلاه لاحظ التالي:

- scorm-again يرسل كائن `cmi` كاملاً في كل حفظ، بخلاف مشغل Moodle الذي رأيناه في المقال السابق يرسل ما تغير فقط، فصمم جدولك ليستبدل الكائن لكل متعلم ومقرر.
- اسم المتعلم ورقمه وصلا من `loadFromJSON`، وهذا الجزء من مسؤولية منصتك، وكذلك إعادة `suspend_data` و`lesson_location` في الفتح التالي، وإلا بدأ المتعلم من الصفر كل مرة.
- الحدث `CommitSuccess` لم يطبع شيئاً في سجل الصفحة، والسيرفر استقبل الطلبات الثلاثة وأجاب 200، فلا تعتمد على هذا الحدث في الإصدار الذي جربناه قبل أن تختبره، واعتمد على سجل الخادم.

وهل تتحقق المكتبة من القيم كما يفعل LMS حقيقي؟ جربنا من صفحة المشغل ثلاث قيم مباشرة على `window.API`:

```javascript
const r = API.LMSSetValue('cmi.suspend_data', 'x'.repeat(5000)); const e = API.LMSGetLastError();
const r2 = API.LMSSetValue('cmi.core.lesson_status', 'done'); const e2 = API.LMSGetLastError();
const r3 = API.LMSSetValue('cmi.completion_status', 'completed'); const e3 = API.LMSGetLastError();
JSON.stringify([r, e, API.LMSGetErrorString(e), r2, e2, API.LMSGetErrorString(e2), r3, e3, API.LMSGetErrorString(e3)]);
```

```text
["true","0","No Error","false","405","Incorrect Data Type","false","401","Not implemented error"]
```

أي أن المكتبة رفضت حالة غير موجودة في المعيار بالخطأ 405، ورفضت عنصراً من SCORM 2004 في API الإصدار 1.2 بالخطأ 401، ولكنها قبلت 5000 حرف في `suspend_data` كما يفعل Moodle بإعداده الافتراضي، فإذا أردت أن تكتشف الحزم التي تتجاوز حد SCORM 1.2 فلا تعتمد على المكتبة في ذلك، وافحص طول القيمة في الخادم الخلفي.

⚠️

قدم الحزم من النطاق نفسه الذي فيه صفحة المشغل، والسبب أن الحزمة تصل إلى `window.parent.API`، والمتصفح يمنع صفحة من نطاق آخر من الوصول إلى كائنات الصفحة الأم، فإذا وضعت الحزم في خدمة تخزين على نطاق مختلف فلن تجد ال API.

## دعم SCORM في منصات التعلم

إذا كنت تختار LMS، أو تختار صيغة تطلبها من المزود، فالجدول التالي يجمع ما تحققنا منه من مصادر رسمية:

| المنصة                                                                                                                                                                                                            | ما تدعمه                                       | المصدر والملاحظة                                                                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Moodle](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-moodle-%D9%85%D9%86%D8%B5%D8%A9-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%B9%D9%84%D9%89-%D8%B3%D9%8A%D8%B1%D9%81%D8%B1%D9%83/)               | SCORM 1.2 مدمج ويجتاز اختبارات المطابقة، وAICC | [سؤال وجواب SCORM](https://docs.moodle.org/503/en/SCORM%5FFAQ?ref=arabroot.io) يقول إن SCORM 2004 غير مدعوم، وحزمة SCORM 2004 البسيطة عملت في مختبرنا                            |
| [Open edX](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-open-edx-%D9%85%D9%86%D8%B5%D8%A9-%D8%A7%D9%84%D9%85%D9%82%D8%B1%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-mooc/) | SCORM 1.2 وSCORM 2004 عبر إضافة                | [SCORM XBlock](https://github.com/overhangio/openedx-scorm-xblock?ref=arabroot.io) برخصة AGPL-3.0، إصدار 19.0.5 في أكتوبر 2026، وتفعله في Advanced Module List للمقرر            |
| [Chamilo](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-chamilo-%D9%85%D9%86%D8%B5%D8%A9-%D8%AA%D8%B9%D9%84%D9%85-%D8%AE%D9%81%D9%8A%D9%81%D8%A9-%D9%88%D8%B3%D9%87%D9%84%D8%A9/)                   | SCORM 1.2                                      | [توثيق Chamilo 1.11](https://github.com/chamilo/chamilo-lms/blob/1.11.x/documentation/readme.html?ref=arabroot.io) يقول إنه لا يطبق كل مواصفات SCORM 1.2 لأن كثيراً منها اختياري |
| [Canvas](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-canvas-lms-%D8%A8%D9%86%D8%B3%D8%AE%D8%AA%D9%87-%D8%A7%D9%84%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9/)                                           | عبر أداة خارجية External Tool                  | لم نتمكن يوم الكتابة من فتح دليل Instructure الرسمي لدعم SCORM، فاسأل مزود منصتك عن الإصدارات المدعومة قبل الشراء                                                                |

ولاحظ ما يقوله ملف README في SCORM XBlock، وهو ينطبق على كل منصة: الحزمة هي التي تقرر متى أكمل المتعلم النشاط، وليس ال LMS، فالحزمة التي لا تكتب حالة الإكمال تترك المتعلم «not attempted» مهما فعل، والإصلاح يكون في أداة التأليف التي أنتجتها.

## من يختار ماذا؟

| حالتك                                            | الأنسب               | والسبب                                                                              |
| ------------------------------------------------ | -------------------- | ----------------------------------------------------------------------------------- |
| فريق تصميم تعليمي متفرغ يبني دورات تفاعلية كثيرة | Articulate 360 AI    | Storyline هو المعيار في هذا العمل ويصدر كل الصيغ حتى cmi5، والسعر يبرره حجم الإنتاج |
| معلمون عندهم عروض PowerPoint جاهزة               | iSpring Suite        | يحول العروض الموجودة إلى حزم SCORM دون أن يتعلم المعلم أداة جديدة                   |
| مصمم واحد يحتاج أداة تجارية لمشروع محدد          | Adobe Captivate      | سعر شهري معلن للفرد بدل اشتراك سنوي لكل مقعد                                        |
| مدرسة أو جهة بلا ميزانية للتراخيص                | eXeLearning          | مجاني ويعمل على سيرفرك في Container واحد، بشرط أن تتابع إعدادات SCORM لكل نشاط      |
| فريق تقني يريد دورات متجاوبة ويتحكم في الكود     | Adapt                | إطار مفتوح بإضافة تتبع دقيقة، ولكنه يحتاج من يشغل Node.js وMongoDB                  |
| محتوى تفاعلي قصير داخل Moodle                    | H5P                  | لا تحتاج SCORM أصلاً، فالمنصة تقرؤه مباشرة                                          |
| منصة خاصة تريد تشغيل حزم المزودين                | scorm-again مع خادمك | المكتبة تطبق ال API، وأنت تكتب التخزين والهوية                                      |
| تشتري حزماً من مزودين كثيرين                     | SCORM Cloud للاختبار | تكشف أخطاء الحزمة قبل أن تصل إلى منصتك، والخطة المجانية تكفي للاختبار               |

## مشكلات شائعة وحلولها

| العرض                                                    | السبب                                             | الحل                                                       |
| -------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------- |
| حزمة eXeLearning تعمل ولا تصل الدرجة                     | تبويب SCORM في النشاط على «Do not save the score» | اختر الحفظ التلقائي، وفعل وضع الاختبار في General settings |
| المحرر يرفض حفظ النشاط برسالة Quiz mode                  | اخترت حفظ الدرجة دون وضع الاختبار                 | فعل وضع الاختبار ثم احفظ                                   |
| لا يوجد SCORM 2004 في قائمة التصدير في eXeLearning 4.0.5 | العنصر مخفي في الواجهة                            | صدر من أداة سطر الأوامر أو من واجهة REST كما في المختبر    |
| النص العربي مختلط الترتيب في الحزمة                      | لغة المشروع بقيت الإنجليزية lang="en"             | اضبط لغة المشروع في الخصائص قبل التصدير، واختبر على منصتك  |
| الحزمة في منصتك لا تجد ال API                            | الحزمة على نطاق مختلف عن صفحة المشغل              | قدم الحزم من النطاق نفسه                                   |
| المتصفح يحمل صفحة المشغل بدل أن يعرضها                   | السيرفر أرسل application/octet-stream             | حدد نوع المحتوى من اسم الملف الفعلي                        |

## تنظيف المختبر

```bash
docker rm -f edu6-exe edu6-scorm-player
docker rmi exelearning/exelearning:v4.0.5
docker compose down -v
```

## تدريب عملي

- أضف إلى خادم المختبر جدولاً بسيطاً، ملف JSON لكل متعلم، يحفظ آخر كائن `cmi`، ثم مرره إلى `loadFromJSON` عند الفتح التالي، وتأكد أن `cmi.core.entry` أصبحت `resume` وأن الحزمة لم تبدأ من الصفر.
- صدر الدورة نفسها من eXeLearning بصيغة SCORM 2004، وشغلها بالملف `dist/scorm2004.min.js` والكائن `Scorm2004API` في الصفحة نفسها، وقارن الكائن الذي يصل إلى `/commit`.

## الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

- كل أداة تأليف جادة تصدر SCORM، والفرق في السعر والمنصة ومن يستخدمها: Articulate 360 AI بـ 1,749 دولاراً للمقعد سنوياً للفرق، وiSpring Suite بـ 970، وCaptivate بـ 39.99 شهرياً، وeXeLearning وAdapt مجانيان.
- eXeLearning 4.0.5 يعمل في Container واحد ويصدر الصيغتين، ولكن الدرجة لا تصل إلا إذا اخترت حفظها وفعلت وضع الاختبار في كل نشاط.
- اختبر الحزمة في SCORM Cloud وفي نسخة تجريبية من منصتك قبل أن يراها الطلاب.
- لتشغيل SCORM في منصتك خذ مكتبة مثل scorm-again للمتصفح، واكتب أنت التخزين وإعادة البيانات والهوية، وقدم الحزم من النطاق نفسه.
- Moodle وChamilo يقرآن SCORM 1.2، وOpen edX يقرأ الصيغتين بإضافة، فاطلب من المزود ما تدعمه منصتك فعلاً.

وفي المقال التالي من السلسلة نقارن SCORM بـ xAPI وcmi5 في [تتبع تقدم المتعلم من SCORM إلى xAPI](https://arabroot.io/articles/%D9%85%D8%B9%D8%A7%D9%8A%D9%8A%D8%B1-%D9%85%D8%AD%D8%AA%D9%88%D9%89-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-scorm-%D8%A7%D9%85-xapi-%D8%A7%D9%85-cmi5/)، لتعرف متى لا يكفيك SCORM.

## سجل التحديثات

- أكتوبر 2026: كتابة المقال وتجربته على eXeLearning 4.0.5 وMoodle 5.3.0 وscorm-again 3.4.7، والأسعار من الصفحات الرسمية في 22 أكتوبر 2026.