Пакетная сборка / загрузка
const url = 'https://example.com/wp-json/wp2lms-pro/embed-packages/v1/batch?blog_id=1';const options = { method: 'POST', headers: {'X-WP-Nonce': '<X-WP-Nonce>', 'Content-Type': 'application/json'}, body: '{"package":{"title":"Курс HTML","files":{"index.html":"<!doctype html><html lang=\"ru\"><title>Старт</title><h1>Старт</h1></html>","module-2.html":"<!doctype html><html lang=\"ru\"><title>Модуль 2</title><h1>Модуль 2</h1></html>"}},"pages":[{"title":"Старт","launch_path":"index.html","slug":"start","page_status":"publish"},{"title":"Модуль 2","launch_path":"module-2.html","slug":"module-2"}],"link_replace":true,"page_status":"publish","alpine":false}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url 'https://example.com/wp-json/wp2lms-pro/embed-packages/v1/batch?blog_id=1' \ --header 'Content-Type: application/json' \ --header 'X-WP-Nonce: <X-WP-Nonce>' \ --data '{ "package": { "title": "Курс HTML", "files": { "index.html": "<!doctype html><html lang=\"ru\"><title>Старт</title><h1>Старт</h1></html>", "module-2.html": "<!doctype html><html lang=\"ru\"><title>Модуль 2</title><h1>Модуль 2</h1></html>" } }, "pages": [ { "title": "Старт", "launch_path": "index.html", "slug": "start", "page_status": "publish" }, { "title": "Модуль 2", "launch_path": "module-2.html", "slug": "module-2" } ], "link_replace": true, "page_status": "publish", "alpine": false }'Создаёт пакет(ы), опционально страницы WordPress и привязки за один запрос (BatchAssembler::run). Это не одиночный POST /packages и не Static Builder сам по себе.
Два режима. Если передан объект package — один пакет на всех: дерево package.files / package.html (html → index.html, если в дереве нет index.html/Index.html), затем либо pages[] (новые или существующие WP-страницы с per-page launch_path), либо materialize_all (как materialize-pages). package.title пустой → «HTML package». Статус пакета всегда publish. Если package есть, массив items игнорируется.
Иначе нужен непустой items[] (иначе 400 embed_packages_batch_empty): по элементу — свой пакет. create_pages по умолчанию true; link_replace по умолчанию true в обоих режимах. Пустой title элемента → «HTML {n}».
build.run при истинном значении пытается запустить AgentBuild; сбой модуля не валит HTTP — сообщение попадает в warnings[], ответ всё равно 201.
Нужно manage_network (multisite) или edit_pages. Cookie + X-WP-Nonce или Application Password.
Authorizations
Заголовок раздела «Authorizations»Parameters
Заголовок раздела «Parameters»Query Parameters
Заголовок раздела «Query Parameters»ID сайта сети (switch_to_blog). Необязательно: по умолчанию текущий блог запроса. Не ID пакета и не page_id. Минимум 1; на одиночном сайте должен совпадать с текущим — иначе 400 embed_packages_invalid_blog. В сети неизвестный сайт или сайт другой сети — 404 embed_packages_unknown_blog.
Example
1Request Bodyrequired
Заголовок раздела «Request Bodyrequired»object
object
Заголовок общего пакета. Необязательно; пусто → «HTML package». Статус записи всегда publish.
HTML, который PHP кладёт в files[‘index.html’], если в дереве ещё нет index.html/Index.html.
Карта относительных путей к содержимому. Ключ — безопасный относительный путь (PackageFilePolicy). Пустой объект PHP не считает деревом. Небезопасный путь — unsafe_path; чужое расширение — disallowed_extension.
Страницы WordPress в режиме общего пакета (объекты, не числа). Если пусто и materialize_all — материализация индекса пакета.
object
Заголовок страницы WordPress. Пусто → имя файла из launch_path или «Page {n}».
Относительный HTML в общем пакете для этой страницы (sanitize как у PagePackageReplace). Не page_id.
Статус этой страницы. Необязательно; иначе body.page_status, иначе publish.
post_name. Необязательно; иначе sanitize имени launch_path без расширения.
ID уже существующей страницы WordPress (post_type=page) для wp_update_post вместо insert. Не ID пакета. 0 или не-страница → создаётся новая.
Alpine на этой странице при link_replace. По умолчанию false.
Режим «пакет на элемент». Игнорируется, если передан объект package. Пустой массив без package — 400 embed_packages_batch_empty.
object
Заголовок пакета (и страницы, если create_pages). Пусто → «HTML {n}».
HTML, который попадает в files[‘index.html’], если такого ключа ещё нет.
Карта относительных путей к содержимому. Ключ — безопасный относительный путь (PackageFilePolicy). Пустой объект PHP не считает деревом. Небезопасный путь — unsafe_path; чужое расширение — disallowed_extension.
Alpine при привязке созданной/обновлённой страницы. По умолчанию false.
Override запуска на странице WordPress. Пусто → launch_path из метаданных пакета.
Статус страницы WordPress, если create_pages. По умолчанию publish.
post_name страницы WordPress, если create_pages.
ID существующей страницы WordPress для update вместо insert. Не ID пакета.
Только режим package: если pages пуст/нет, вызвать PagesMaterializer. По умолчанию false.
Только режим items: создавать/обновлять страницы WordPress. Необязательно, по умолчанию true.
Сразу PagePackageReplace::save на созданных страницах. Необязательно, по умолчанию true.
Дефолтный статус страниц (materialize_all и pages[] без своего page_status). По умолчанию publish.
Alpine для materialize_all в режиме package. По умолчанию false. В pages[]/items[] есть свой alpine.
object
Если истинно — после ingest вызвать AgentBuild (BuildService::create + run). Сбой модуля не меняет HTTP-код, текст идёт в warnings[].
Дополнительные ID страниц WordPress к тем, что создал batch. Не ID пакетов.
Course_name сборки. Необязательно, по умолчанию «Agent embed batch».
Api_type сборки. Необязательно, по умолчанию local (sanitize_key).
Export_mode сборки. Необязательно, по умолчанию package.
ID главной страницы WordPress для AgentBuild, если ключ передан.
Строковый course_id сборки, если ключ передан.
Версия сборки ((float)), если ключ передан.
Второй аргумент BuildService::run($id, $sync). По умолчанию false.
Example
{ "package": { "title": "Курс HTML", "files": { "index.html": "<!doctype html><html lang=\"ru\"><title>Старт</title><h1>Старт</h1></html>", "module-2.html": "<!doctype html><html lang=\"ru\"><title>Модуль 2</title><h1>Модуль 2</h1></html>" } }, "pages": [ { "title": "Старт", "launch_path": "index.html", "slug": "start", "page_status": "publish" }, { "title": "Модуль 2", "launch_path": "module-2.html", "slug": "module-2" } ], "link_replace": true, "page_status": "publish", "alpine": false}Responses
Заголовок раздела «Responses»Сборка выполнена. Режим package — package_id, meta, launch_url, pages[], is_multipage. Режим items — items[]. Всегда blog_id; опционально build и warnings.
Форма зависит от режима. package — package_id, meta, launch_url, pages, is_multipage. items — items[]. RestApi всегда добавляет blog_id. build — только если build.run сработал без WP_Error; иначе текст в warnings.
object
ID общего пакета (режим package). В режиме items поля нет.
Полный массив post meta _wp2lms_embed_package (PackageMeta::get). У пакета без ingest — пустой объект.
object
Тип после ManifestPipeline — web, scorm1.2, scorm2004 или xapi. Пусто, пока содержимое не залито.
Версия из манифеста (для SCORM часто совпадает с content_type). Для web обычно пустая строка.
XAPI activity id. Если парсер не дал — {home}wp2lms-embed-package/{id}.
Относительный HTML запуска внутри storage (из манифеста или fallback index.html).
Заголовок из launch HTML / манифеста; PHP может перезаписать post_title пакета этим значением.
Mastery score из imsmanifest (SCORM), иначе null.
Детектор автора: ispring, articulate_rise, articulate_storyline, articulate_presenter, captivate, elucidat или пустая строка.
Путь от uploads basedir, wp2lms-embed-packages/{id}/.
Unix-время последней успешной записи содержимого (time() в finalize).
True только для content_type=web без content_tool и ≥2 HTML в индексе.
Индекс HTML (path+title), если пакет multipage; иначе [].
object
Относительный путь HTML внутри каталога пакета (posix, без ведущего /). Из PackagePagesIndex::scan.
Заголовок из <title> файла или имя без расширения, если тега нет.
URL запуска общего пакета (режим package).
Страницы WordPress в режиме package (не путать с meta.pages внутри пакета).
object
ID созданного общего пакета.
ID страницы WordPress (созданной или обновлённой). Не ID пакета.
Заголовок страницы, как записали в batch.
Slug, который ушёл в post_name (может быть пустым, если не задавали и не вывели из launch_path).
Путь запуска страницы (override или дефолт пакета).
Копия is_multipage общего пакета (режим package).
Результаты режима items[] (по одному пакету на элемент).
object
ID пакета, созданного для этого элемента items[].
ID страницы WordPress либо null, если create_pages=false.
Заголовок элемента (пакет/страница).
Override или launch_path из meta пакета.
Абсолютный URL запуска этого пакета.
Полный массив post meta _wp2lms_embed_package (PackageMeta::get). У пакета без ingest — пустой объект.
object
Тип после ManifestPipeline — web, scorm1.2, scorm2004 или xapi. Пусто, пока содержимое не залито.
Версия из манифеста (для SCORM часто совпадает с content_type). Для web обычно пустая строка.
XAPI activity id. Если парсер не дал — {home}wp2lms-embed-package/{id}.
Относительный HTML запуска внутри storage (из манифеста или fallback index.html).
Заголовок из launch HTML / манифеста; PHP может перезаписать post_title пакета этим значением.
Mastery score из imsmanifest (SCORM), иначе null.
Детектор автора: ispring, articulate_rise, articulate_storyline, articulate_presenter, captivate, elucidat или пустая строка.
Путь от uploads basedir, wp2lms-embed-packages/{id}/.
Unix-время последней успешной записи содержимого (time() в finalize).
True только для content_type=web без content_tool и ≥2 HTML в индексе.
Индекс HTML (path+title), если пакет multipage; иначе [].
object
Относительный путь HTML внутри каталога пакета (posix, без ведущего /). Из PackagePagesIndex::scan.
Заголовок из <title> файла или имя без расширения, если тега нет.
ID сайта после switch. RestApi дописывает всегда.
Обёртка AgentBuild { created, run }, если build.run истинно и модуль ответил не WP_Error. Иначе поля нет.
object
Сообщения (например AgentBuild недоступен). Не меняют HTTP 201.
Example
{ "package_id": 42, "meta": { "content_type": "web", "version": "", "activity_id": "https://lms.example.com/wp2lms-embed-package/42", "launch_path": "index.html", "title": "Курс HTML", "mastery_score": null, "content_tool": "", "storage_rel": "wp2lms-embed-packages/42/", "uploaded_at": 1726252800, "is_multipage": true, "pages": [ { "path": "index.html", "title": "Старт" }, { "path": "module-2.html", "title": "Модуль 2" } ] }, "launch_url": "https://lms.example.com/wp-content/uploads/wp2lms-embed-packages/42/index.html", "pages": [ { "package_id": 42, "page_id": 128, "title": "Старт", "slug": "start", "launch_path": "index.html" }, { "package_id": 42, "page_id": 129, "title": "Модуль 2", "slug": "module-2", "launch_path": "module-2.html" } ], "is_multipage": true, "blog_id": 1}Embed_packages_batch_empty — нет package-объекта и пустой items[]; embed_packages_batch_package — package не объект; embed_packages_batch_page — pages[n] не объект; embed_packages_batch_item — items[n] не объект; embed_packages_invalid_blog — некорректный blog_id.
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}Не аутентифицирован. WordPress REST: rest_forbidden (status 401), если нет cookie-сессии. Cookie + X-WP-Nonce или Application Password.
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}Нет права manage_network (multisite) или edit_pages (одиночный сайт), либо невалидный REST nonce (rest_cookie_invalid_nonce).
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}Embed_packages_unknown_blog — в сети нет такого сайта или сайт принадлежит другой сети.
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}WP_Error без HTTP-status — сбой wp_insert_post/wp_update_post или ingest дерева (empty_tree, unsafe_path, disallowed_extension, process_failed, write_failed и др.). WordPress REST отдаёт такие ошибки как 500.
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}